Cross posting my answer to a DynamoBim question where they were trying to redraw wall types in a legend view to provide snap and dimension capability. This will instead add reference planes - keeping the legend component intact. I’ll probably polish it a bit more for floor and ceilings and add it to my collection. Handy enough.
import math
from Autodesk.Revit.DB import *
elements = FilteredElementCollector(doc, doc.ActiveView.Id) \
.OfCategory(BuiltInCategory.OST_LegendComponents) \
.WhereElementIsNotElementType() \
.ToElements()
def draw_reference(element, elemtype, view_direction):
angle = -math.pi / 2
bubble_dir = XYZ(0, 0, 1)
width_param = element.LookupParameter("Host Length")
if not width_param or not width_param.HasValue:
return
width = width_param.AsDouble()
compound_structure = elemtype.GetCompoundStructure()
if not compound_structure:
return
layer_widths = [layer.Width for layer in compound_structure.GetLayers() if layer.Width > 0]
bbox = element.BoundingBox[doc.ActiveView]
if not bbox:
return
max_pt = bbox.Max
axis = Line.CreateBound(max_pt, max_pt + XYZ(0, 0, 1))
start_pt = max_pt
end_pt = XYZ(start_pt.X - width, start_pt.Y, start_pt.Z)
start_plane = doc.Create.NewReferencePlane(start_pt, end_pt, bubble_dir, doc.ActiveView)
if view_direction == "Section":
ElementTransformUtils.RotateElement(doc, start_plane.Id, axis, angle)
ElementTransformUtils.MoveElement(doc, start_plane.Id, XYZ(0, -width, 0))
for layer_width in layer_widths:
start_pt = XYZ(start_pt.X, start_pt.Y - layer_width, start_pt.Z)
end_pt = XYZ(end_pt.X, end_pt.Y - layer_width, end_pt.Z)
ref_plane = doc.Create.NewReferencePlane(start_pt, end_pt, bubble_dir, doc.ActiveView)
if view_direction == "Section":
ElementTransformUtils.RotateElement(doc, ref_plane.Id, axis, angle)
ElementTransformUtils.MoveElement(doc, ref_plane.Id, XYZ(0, -width, 0))
t = Transaction(doc, "Draw Reference Planes")
t.Start()
for element in elements:
try:
type_id = element.LookupParameter("Component Type").AsElementId()
elemtype = doc.GetElement(type_id)
if isinstance(elemtype, WallType):
view_dir_param = element.LookupParameter("View Direction")
if view_dir_param and view_dir_param.HasValue:
view_direction = view_dir_param.AsValueString()
draw_reference(element, elemtype, view_direction)
except Exception as e:
print(f"Error processing element {element.Id}: {e}")
t.Commit()