Let's start this week with the following topics from freecodecamp and the Revit API discussion forum:
Here are a couple of recent articles I found interesting, pointed out in the freecodecamp newsletter:
"To err is human. But to really foul things up, you need a computer." – Paul Ehrlich
Back to the Revit API and some useful solutions discussed in the Revit API discussion forum:
There seem to be some issues handling Cyrillic characters in lookup tables, as pointed out in the thread on Russian letters doesn't export in lookup tables. Happily, however, at least a partial solution can be found:
... it works. Now, when he switches to the Russian keyboard, he can insert a CSV to a family with Cyrillic text with no loss.
Matt Taylor very kindly pointed out the solution to another old thread on moving a grid:
I would guess that the grid cannot be moved because it doesn't have a leader. Use the
AddLeader
method to add a leader first. You'll also probably need to do adocument.Regenerate
afterwards, before you set the leader points.I found the old blog post that contains the code. Seeing the code, I can confirm that my guess was correct.
To wrap it up, Lucas Moreira shared a more complex solution to combine connected edge segments into one continuous line:
Question: 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, cf., the orange and red semi-segments below:
Two semi segments forming an edge
How can I 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 retrieving the segments using the Face.EdgeLoops
property.
Answer: Two steps:
Here are hints from StackOverflow for the first:
The Building Coder provides 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.
Response: 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 all the Edges.AsCurveLoops
, separating the horizontally aligned ones.
The algorithm evaluates that list and groups 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 curve start points with their matching endpoints and use the unmatched points to form my 'new' undivided edge curve.
I will use the logic
in sorting vertices of a polygon in CCW or CW direction for
that.
I know that this code can be optimized, 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
Many thanks to Lucas for raising and solving this interesting task.