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
AddLeadermethod to add a leader first. You'll also probably need to do adocument.Regenerateafterwards, 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.