Dimension Wall Legend Components

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()
1 Like