This is the code written below. In the “Main Body”, I got some error in the except function. The warning shows AttributeError : ‘ArgumentException’ object has no attribute ‘message’.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript import Geometry as geom
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
Convert to list if not list…
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
Getting the centreline of the column…
def GetColumnCentreline(e):
crv = None
fs = e.Symbol
fm = fs.Family
if not fm.GetType() == DirectShape:
if not fm.IsInPlace:
if e.IsSlantedColumn:
try:
crv = e.Location.Curve.ToProtoType()
except:
return
else:
loc = e.Location.Point.ToPoint()
bLev = (e.Document.GetElement(e.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).AsElementId()).Elevation + e.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).AsDouble()) * ft2mm
tLev = (e.Document.GetElement(e.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).AsElementId()).Elevation + e.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).AsDouble()) * ft2mm
crv = geom.Line.ByStartPointEndPoint(geom.Point.ByCoordinates(loc.X,loc.Y,bLev), geom.Point.ByCoordinates(loc.X,loc.Y,tLev))
return crv
Convert Level to DS Plane…
def LevelToPlane(l):
pt = geom.Point.ByCoordinates(0,0,round(l.Elevation * ft2mm,0)+offset)
n = geom.Vector.ZAxis()
return geom.Plane.ByOriginNormal(pt,n)
Get the nearest Level above in list of Levels to gien Elevation…
def NearestLevelAbove(elev,lvls):
lvlAbv = None
for l in lvls:
if round(l.Elevation*ft2mm,0) > elev:
lvlAbv = l
break
return lvlAbv
Get the nearest Level in list of Levels to gien Elevation…
def NearestLevel(elev, lvls):
return min(lvls, key=lambda x:abs(round(x.Elevation*ft2mm,0)-elev))
Calculates the location to split column with parameterised column length (between 0 & 1)…
def CalculateSplitParameter(col,lvls):
Switch out for mathematical method to speed up computation…
# abs(NewColBaseElevation-LevelAboveElevation)/NewCol length should give split parameter...
if col:
crv = GetColumnCentreline(col)
elev = round(crv.StartPoint.Z,0)
l = NearestLevelAbove(elev,lvls)
x = geom.Geometry.Intersect(crv,LevelToPlane(l))
if x:
x = x[0]
return geom.Curve.ParameterAtPoint(crv,x)
return None
# IN Variables...
run = tolist(IN[0])[0]
columns = tolist(UnwrapElement(IN[1]))
lvls = tolist(UnwrapElement(IN[2]))
offset = 0
if IN[3]:
offset = tolist(IN[3])[0]
# OUT Variables...
outList = []
Main Body…
if run:
ft2mm = 304.8
lvls = sorted(lvls, key=lambda x: x.Elevation)
# Start Transaction to allow for Document modification...
TransactionManager.Instance.EnsureInTransaction(doc)
for c in columns:
# Ensure only Structural Columns are used (modify if Arch Columns category is required)
if c.Category.Name == Category.GetCategory(doc,BuiltInCategory.OST_StructuralColumns).Name:
arr = []
arr.append(c)
newCol = None
crv = GetColumnCentreline(c)
bLvlIndex = lvls.index(NearestLevel(crv.StartPoint.Z,lvls))
tLvlIndex = lvls.index(NearestLevel(crv.EndPoint.Z,lvls))
i = bLvlIndex
while i <= tLvlIndex:
try:
if not newCol:
p = CalculateSplitParameter(c,lvls)
newCol = doc.GetElement(c.Split(p))
arr.append(newCol)
else:
p = CalculateSplitParameter(newCol,lvls)
newCol = doc.GetElement(newCol.Split(p))
arr.append(newCol)
except Exception as ex:
arr.append(ex.message)
i = i+1
outList.append(arr)
else:
outList.append("Element is not of Category Structural Column")
TransactionManager.Instance.TransactionTaskDone()
OUT = outList
else:
OUT = "Please set Run to True"`
This was in Revit dynamo script. The main objective is split the column at the location of level planes.
Kevin Trimocha Manalo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.