Hello everyone,
I am currently stuck on a problem with Python. I am trying to find the lines in a list of lines that overlap (i.e. have the same direction and a common intersection). I want to output the lines in a list of merged lines. I would then like to keep the intersection points (or midpoints of the intersection lines) determined in a separate list for each line. Unfortunately, I am currently stuck in a While loop.
In the example, all 4 lines would fulfil the above condition. I would therefore have to obtain a line with 3 intersection points. Apparently, the script only executes the While loop correctly for the first two lines. I have already tried to control this with bool flags or with a continue command. Unfortunately, none of this changes the output. I am a bit at a loss at the moment. Can anyone tell me what I am missing here?
import clr
clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry as DS
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
#define function
def bool_overlapping_lines(line1, line2) :
if line1.Direction.IsAlmostEqualTo(line2.Direction) and line1.DoesIntersect(line2) :
return True
else :
return False
def merge_lines(line1, line2) :
#get startpoint and endpoint of both lines
start1, end1 = line1.StartPoint, line1.EndPoint
start2, end2 = line2.StartPoint, line2.EndPoint
#get common endpoints
common_start = min(end1,end2)
common_end = max(start1,start2)
#Create new line
merged_line = DS.Line.ByStartPointEndPoint(common_start, common_end)
return merged_line
def get_intersection_point_2lines(line1,line2) :
#get intersecting geometry
intersection = line1.Intersect(line2)
#get point of intersection
if intersection[0].GetType() == DS.Line :
intersection_point = intersection[0].PointAtParameter(0.5)
elif intersection[0].GetType() == DS.Point :
intersection_point = intersection[0]
else :
intersection_point = "Failed"
return intersection_point
#Create access to current revit document
doc = DocumentManager.Instance.CurrentDBDocument
#Get input data
lines = UnwrapElement(IN[0])
#Start transaction
TransactionManager.Instance.EnsureInTransaction(doc)
lines_edit = list(lines) #creates editable copy of lines
points = [] #create empty list to store intersection points
merging_process = True
while merging_process :
i = 0 # Set basic counter to zero
merging_process = False
while i < len(lines_edit):
j = i + 1 # Set sub counter to the next line after i
point_cache = [] # Create an empty cache list to store intersection points per wall
while j < len(lines_edit):
if bool_overlapping_lines(lines_edit[i], lines_edit[j]): # If lines do intersect
intersec_pt = get_intersection_point_2lines(lines_edit[i], lines_edit[j]) # Get the intersection point
point_cache.append(intersec_pt) # Store the intersection points in a cache list until all overlapping lines of this wall are merged
lines_edit[i] = merge_lines(lines_edit[i], lines_edit[j]) # Merge lines together and overwrite line1
lines_edit.pop(j) # Remove line2 (lines_edit[j]) as it is included in line1 (lines_edit[i]) now
merging_process = True
else:
j += 1 # If lines do not overlap, move to the next line
i += 1 # Move to the next line i
points.append(point_cache) # Store results from intersection points in a list
#End transaction and save changes
TransactionManager.Instance.TransactionTaskDone()
#output
OUT = lines_edit, points