Changing Leader Arrows

I’m having a hard time understanding how to change leader arrowheads on a symbol. It appears to be possible through Dynamo—does the API allow us to access this with Python? Just need a simply way to change the arrowhead style of all selected symbols. As this is usually a type parameter, I need to go through and change each type manually which would be too time consuming.

Following up. I’m assuming this isn’t possible?

It is definitely possible.
Not in front of a computer but I will put a snippet here if I get the time tomorrow

Thanks, Jean-Marc…as long as I know it’s possible I will keep on trying. I just didn’t want to keep on attempting something that Pyrevit couldn’t do.

Hi Aaron,

What symbols do you mean? Door/window tags? How many types of them do you have in the project? If it’s a type parameter, if you change it in the type editor, it will change for all tags of that type. If it’s an instance parameter, you can select multiple of them and change it in the properties panel.

For selecting all symbols of the same type you can go to the families browser, right click a type and choose Select All Instances (there’s also a standard keyboard shortcut for that - click on an element, then SA and it will select all elements of the same type).

For arrowheads, there’s also an often overlooked section in Manage > Additional Settings > Annotations > Arrowheads.

For more complicated cases (for example you want to change it for some elements of different types, but not for others of the same type) - as Jean-Marc wrote, it is most likely possible since Revit API allows changing type and instances’ parameters and also creating new types if needed.

I want to change the arrowhead of a leader belonging to a generic annotation. While these are type parameters, if I have multiple types belonging to a single family, changing the arrow heads can be time consuming. It’s not a critical add, but a quick python script would be very beneficial if I could figure out how to get to those through Python.

You can do that with other tools,
diRoots sheetlink in its free tier allow you to do this.

I don’t usually code instead of people in the forum, but this one picked my interest (and you should always provide your train of thought or basic code trials.

Nice little challenge in the end, really thought that would have been easier, there are a few weird Revit API stuff that needs considering:

  • ElementType Class for all arrow heads
  • ElementType Name classical .NET implementation issue
  • “Arrowhead” family name removal to get only the actual arrow heads type
  • Excluding generic annotation without the LEADER_ARROWHEAD parameter
# encoding: utf-8
from pyrevit import revit, DB, forms, script
from collections import OrderedDict

script.get_output().close_others()

doc = revit.doc


def get_name(element):
    """Get the name of the element."""
    return DB.Element.Name.__get__(element)


generic_annotation_collector = [
    _
    for _ in DB.FilteredElementCollector(doc)
    .OfCategory(DB.BuiltInCategory.OST_GenericAnnotation)
    .WhereElementIsElementType()
    .ToElements()
    if _.get_Parameter(DB.BuiltInParameter.LEADER_ARROWHEAD) is not None
]
generic_annotation_sorted_dict = OrderedDict(
    sorted(
        {
            get_name(generic_annotation): generic_annotation
            for generic_annotation in generic_annotation_collector
        }.items()
    )
)
generic_annotation_selection = forms.SelectFromList.show(
    generic_annotation_sorted_dict.keys(),
    title="Select Generic Annotation Type",
    multiselect=True,
    width=400,
    height=300,
    exitscript=True,
)
if not generic_annotation_collector:
    forms.alert("No generic annotation types found in the document.", exitscript=True)
generic_annotation_types = []
for generic_annotation in generic_annotation_collector:
    if str(get_name(generic_annotation)) in generic_annotation_selection:
        generic_annotation_types.append(generic_annotation)

arrow_heads_types = [
    _
    for _ in DB.FilteredElementCollector(doc)
    .OfClass(DB.ElementType)
    .WhereElementIsElementType()
    .ToElements()
    if _.FamilyName == "Arrowhead"
]
available_arrowhead_types = OrderedDict(
    sorted(
        {
            get_name(arrow_head): arrow_head
            for arrow_head in arrow_heads_types
            if get_name(arrow_head) != "Arrowhead"
        }.items()
    )
)
picked_arrow_head = forms.SelectFromList.show(
    available_arrowhead_types.keys(),
    title="Select Arrowhead Type",
    multiselect=False,
    width=400,
    height=300,
    exitscript=True,
)
if not picked_arrow_head:
    forms.alert("No arrowhead type selected.", exitscript=True)

chosen_arrowhead = available_arrowhead_types.get(picked_arrow_head)

with revit.Transaction("Set Arrowhead Type for Generic Annotations"):
    for generic_annotation_type in generic_annotation_types:
        param = generic_annotation_type.get_Parameter(
            DB.BuiltInParameter.LEADER_ARROWHEAD
        ).Set(chosen_arrowhead.Id)
1 Like

Thanks, Jean-Marc. I was not expecting it to be this in-depth. (The help or the task). I saw mention of the need for a community repository. I’d like to 2nd that. There is a lot of knowledge and work that can be shared.