I am trying to get dynamo to provide the X,Y,Z of the start and end nodes of each column. To do so, I have realized that columns are not quite so user-friendly as framing is.
So it looks like I have to use Clockwork to get Element.Location for the columns. However, when I do so, the Z value for each location point is equal to Zero ft, no matter how high or what offset I put on the column (See attached image). Is this the way it is supposed to work?
I have created a functional workaround that involves pulling the Base Level of each column, pulling the location of each level, then correcting the Z value by adding the Level Location, but i’d rather do it the right way if there is such a thing.
My first try was by changing the column style to “slanted-end point driven” and it worked fine except that I got a message to ungroup all columns. Seems that changing the column style cannot be done for groups.I also tried the Bounding box method, but it gives the “bounding box” of the column, not the center, so a formula to get the center is probably needed.
It’s good enough, but maybe there is a better way. ideas ?
Or you can use the X and Y from Element.Location node and just extract the Z-value from the bounding box method. Dimitars DS-code is way cooler though…
I’m with Timon on this - what you showed only will work if the columns are slanted column. It is possible to change the columns to slanted, pull the locations and/or curves, then switch back to vertical columns, but that taxes the system pretty good if you have more than a handful of columns (note the conversation in the post Einar referenced)
Timon-
Try this bit of Python Script (it’s essentially a modification of element .location + the top and bottom offset calculations)
import clr
import math
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.AddReference("DSCoreNodes")
from DSCore import*
doc = DocumentManager.Instance.CurrentDBDocument
columnz = UnwrapElement(IN[0])
projectElevBool = IN[1]
startpointlist = list()
endpointlist = list()
rotations = list()
curves = list()
columnstyle=list()
for col in columnz:
paramlist = col.Parameters
rotparam = BuiltInParameter.STRUCTURAL_BEND_DIR_ANGLE
colstyle=-1
baselevel = -1
toplevel=-1
baseoff ='nada'
topoff = 'nada'
for p in paramlist:
if p.Definition.Name =='Column Style':
colstyle = col.get_Parameter(p.Definition).AsInteger()
if p.Definition.Name =='Base Level':
baselevel= doc.GetElement(col.get_Parameter(p.Definition).AsElementId())
if p.Definition.Name =='Base Offset':
baseoff= col.get_Parameter(p.Definition).AsDouble()
if p.Definition.Name =='Top Level':
toplevel= doc.GetElement(col.get_Parameter(p.Definition).AsElementId())
if p.Definition.Name =='Top Offset':
topoff= col.get_Parameter(p.Definition).AsDouble()
if projectElevBool == True:
basel = baselevel.ProjectElevation
topel = toplevel.ProjectElevation
else:
basel = baselevel.Elevation
topel = toplevel.Elevation
if colstyle ==0:
columnloc =col.Location.Point
rotations.append(math.degrees(col.Location.Rotation))
#rotations.append(col.Location.Rotation)
newXYZbottom =XYZ(columnloc.X,columnloc.Y,basel + baseoff)
newXYZTop =XYZ(columnloc.X,columnloc.Y,topel + topoff)
startpointlist.append(newXYZbottom.ToPoint())
endpointlist.append(newXYZTop.ToPoint())
curves.append(Line.ByStartPointEndPoint(newXYZbottom.ToPoint(),newXYZTop.ToPoint()))
columnstyle.append(0)
elif colstyle ==1 or colstyle ==2:
startpointlist.append(col.Location.Curve.GetEndPoint(0).ToPoint())
endpointlist.append(col.Location.Curve.GetEndPoint(1).ToPoint())
rotations.append(math.degrees(col.get_Parameter(rotparam).AsDouble()))
#rotations.append(col.get_Parameter(rotparam).AsDouble())
curves.append(col.Location.Curve.ToProtoType())
columnstyle.append(2)
else:
columnloc =col.Location.Point
rotations.append(math.degrees(col.Location.Rotation))
newXYZbottom =XYZ(columnloc.X,columnloc.Y,basel + baseoff)
newXYZTop =XYZ(columnloc.X,columnloc.Y,topel + topoff)
startpointlist.append(newXYZbottom.ToPoint())
endpointlist.append(newXYZTop.ToPoint())
rotations.append(-1*math.degrees(col.Location.Rotation))
#rotations.append(col.Location.Rotation)
curves.append(Line.ByStartPointEndPoint(newXYZbottom.ToPoint(),newXYZTop.ToPoint()))
columnstyle.append(0)
OUT = (startpointlist,endpointlist,curves,rotations,columnstyle)
@Ben_Osborne… you hit the nail on the head. Vertical columns “location” is actually just a point. That’s where you started this conversation a while back. The python you have written out looks quite like the image I posted in Reply 9. Have you published that in a package?
@kulkul. I was so excited thinking that you were working with vertical columns.
It’s basically the same as what you showed, except your Dyn left out any accounting for offsets from the Base Level or Top Level - in my experience bottom of column is usually offset below the base level of the building