Merge lines and store intersection points

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

image

I’m going to assume the list of curves is at least already ordered. If it’s not, you should work on that first. It will be much easier stepping through an ordered list of curves than trying to determine which curves intersect within the same process.

  1. Get the start and end points of the first curve and store them.
  2. Step through the rest of the curves in the list.
  3. For each curve, compare its start and end points to the previous curve’s.
  4. Take the end point of the previous curve and the start point of the current curve and average them.

Unfortunately in reality, these will be several lines with different directions that are distributed differently in space. The example above ist just the easiest case. So I can’t think of a reasonable order in which to sort the curves.

I actually thought that the recursive while loop should do the job. Do you see any error in there?