Combine connected edge segments into one continuous line.

Combine connected edge segments into one continuous line.

lucas-gsbp
Contributor Contributor
3,848 Views
3 Replies
Message 1 of 4

Combine connected edge segments into one continuous line.

lucas-gsbp
Contributor
Contributor

Hello,

I am fetching the edge loops of a face. When I do so, depending on the original geometry that created the solids, these loop segments can be composed of 2 or more subsegments to form an edge see the orange and red semi-segments bellow:

2 semi segments forming a edge2 semi segments forming a edge

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I am failing to identify and retrieve a continuous line for each edge.

Is there a way I can do that recursively regardless of the number of segments forming the edge?

I am coding for Revit 2019 and I am retrieving the segments using the Face EdgeLoops property

 

Thanks for the help.

0 Likes
Accepted solutions (1)
3,849 Views
3 Replies
Replies (3)
Message 2 of 4

jeremytammik
Autodesk
Autodesk
  • Step 1: Sort the edges so they in the right order
  • Step 2: combine all groups of consecutive collinear edges into single ones

 

Here is a hint for Step 1:

 

 

Here are some older thoughts on sorting and orienting curves to form a contiguous loop:

 

 

One method that does part of the work that you should definitely be aware of is the Edge.AsCurveFollowingFace method that returns a curve corresponding to the edge oriented in its topological direction on the specified face. That is the simplest option and a good place to start.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 4

lucas-gsbp
Contributor
Contributor
Accepted solution

Hi Jeremy,

First of all, Thank you, that helped me a lot and I am really close to a solution.

My scenario is slightly different as I am only using horizontally aligned edges of the exterior face of the geometry, I think it actually makes it easier because I don't have to sort the edges but sort only the segments that would compose one straight edge.

I used the python node on dynamo to prototype what I need (The visual 3d space there helps me with debugging).

What I am doing is getting a list with al the Edges.AsCurveLoops separating the horizontally aligned ones, the algorithm will evaluate that list and will group the curves to be joined into sublists because I was already making sure that all the curves are oriented in the same direction I just need to  pair the curves start points with its matching endpoints until and use the unmatched points  to form my "new" undivided edge curve, I will use the logic in here: https://stackoverflow.com/questions/13114378/sorting-vertices-of-a-polygon-in-ccw-or-cw-direction for that.

I know that this code can be optimized up but I will post it here for the sake of completion. It might help someone.

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
#from Revit import GeometryConversion as gp

import math

curves = IN[0]
#The next 2 methods will assume that the directions is known.
#The start point of a curve
def startPoint(curve):
    return curve.GetEndPoint(0)

#The end point of a curve
def endPoint(curve):
    return curve.GetEndPoint(1)
#Groups lines to be joined in sublists with the curves that have to be joined    
def joinCurves(list):
	comp=[]
	re=[]
	unjoined = []
	for c in curves:
		c = c.ToRevitType()
		match = False
		for co in comp:
			if startPoint(c).IsAlmostEqualTo(startPoint(co)) and endPoint(c).IsAlmostEqualTo(endPoint(co)):
				match = True
		if match:
			continue
		else:
			comp.append(c)			
			joined = []
			for c2 in curves:
				
				match = False
				c2 = c2.ToRevitType()
				for co in comp:
					if startPoint(c2).IsAlmostEqualTo(startPoint(co)) and endPoint(c2).IsAlmostEqualTo(endPoint(co)):
						match = True
				if match:
					continue
				else:
					if c2.Intersect(c) == SetComparisonResult.Disjoint:
						continue
					elif c2.Intersect(c) ==  SetComparisonResult.Equal:
						continue
					elif c2.Intersect(c) == SetComparisonResult.Subset:
						comp.append(c2)
						joined.append(c2.ToProtoType())
		joined.append(c.ToProtoType())
		re.append(joined)
		
	return re
		
result = joinCurves(curves)
OUT = result

Cheers,

0 Likes
Message 4 of 4

jeremytammik
Autodesk
Autodesk

Dear Lucas,

 

I am very glad that it helped! 

 

Thank you for the appreciation and sharing your experimental code.

 

Yes, it looks as if some optimisation and cleanup can be done, and it can be made a bit shorter and more readable.

 

Cheers,

 

Jeremy

  



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder