Best way to toggle FilteredElementCollector view/entire doc

revit
api

#1

My code is already working, it’s just a simple script for changing the text type of every TextNote in my file with one caveat.
It’s a large file with hundreds of views so if I mess up something, I might not be able to keep track of the damage I’ve done so I might need to do the replacements by view to I can keep track of it.

So… I simply created a toggle between FilteredElementCollector(doc) and FilteredElementCollector(doc, doc.ActiveView.Id). Whenever I switch the toggle to Active Views only though, the collector returns nothing, I have no idea why.

Am I doing something wrong?

Main part of code:

toggle = bool(IN[0])

# 2.0mm ISO
type_2 = UnwrapElement(IN[1])

# 2.3mm ISO
type_2_3 = UnwrapElement(IN[2])

# toggle: active view only
active_view_only = bool(IN[3])



def view_toggle():
    """if True: run only for active view, False: entire doc"""
    return FilteredElementCollector(doc, doc.ActiveView.Id)                 \
                    if active_view_only is True                             \
                    else FilteredElementCollector(doc)


# limit to active view first
# TODO: VERY IMPORTANT
# LIMIT ONLY TO SHEET VIEWS??? (or exclude sheet views?) (might not be nec)
text_note_collector = view_toggle().                                        \
                        OfCategory(BuiltInCategory.OST_TextNotes)

.
.
.
Rest of the code:
.
.
.

if toggle is True:
    # TransactionManager.Instance.EnsureInTransaction(doc)

    unchanged_text = []

    num_of_elements_before = view_toggle().                                 \
                                OfClass(clr.GetClrType(TextElement)).       \
                                ToElementIds().                             \
                                Count

    with Transaction(doc, 'Change Note Types') as t:
        t.Start()

        # try:
        for text in text_note_collector:

            text_note_type  = text.TextNoteType
            text_size_param = BuiltInParameter.TEXT_SIZE

            text_size       = text_note_type.get_Parameter(text_size_param).AsDouble()
            text_size       = UnitUtils.ConvertFromInternalUnits(text_size,
                                                                 DisplayUnitType.DUT_MILLIMETERS)

            if 0 <= text_size <= 2.1:
            # change size to 2.0
                text.TextNoteType = type_2
                unchanged_text.append(text)

            # change size to 2.3 (gt than 2.1 but less than 3)
            elif 2.111111 <= text_size <= 3:
                text.TextNoteType = type_2_3
                unchanged_text.append(text)

            else:
                # append the UNchanged textNotes for viewing in Dynamo
                unchanged_text.append([text, 'Unchanged'])
                # symbols.append(text.Symbol)

        num_of_elements_after = view_toggle().                              \
                                    OfClass(clr.GetClrType(TextElement)).   \
                                    ToElementIds().                         \
                                    Count

        # assert that num of TextNotes is the same before and after
        if num_of_elements_before != num_of_elements_after:
            t.RollBack()
            OUT = 'Error Occurred, Some items were deleted'

        else:
            t.Commit()
            OUT = unchanged_text

    # TransactionManager.Instance.TransactionTaskDone()




# just display the TextNotes if toggle = False
else:
    OUT = [text.ToDSType(False) for text in text_note_collector]
    #OUT = text_note_collector.ToElementIds().Count

I also have this problem popping up (tried it on dummy files) when doing a lot of changes. I tried to suppress this using the IFailuresProcessor but apparently it doesn’t catch this. How to I catch this type of error?

image

Here:s what I did:

class MyFailureHandler(IFailuresPreprocessor):

    def processFailures(failures_accessor):
        # doc = failures_accessor.GetDocument()
        failuresAccessor.DeleteAllWarnings()

        return FailureProcessingResult.Continue

if toggle is True:
    # TransactionManager.Instance.EnsureInTransaction(doc)

    unchanged_text = []

    num_of_elements_before = view_toggle().                                 \
                                OfClass(clr.GetClrType(TextElement)).       \
                                ToElementIds().                             \
                                Count

    with Transaction(doc, 'Change Note Types') as t:
        t.Start()
        fail_opt = t.GetFailureHandlingOptions()
        fail_opt.SetFailuresPreprocessor(MyFailureHandler())
        t.SetFailureHandlingOptions(fail_opt)

      (...the Rest = same code)

#2

What version of Revit are you using? This would be great use for Dynamo Player if you have it available.


#3

2018

Edit: I edited the original post, another problem popped up.


#4

I would definitely suggest Dynamo Player then. It will rerun your graph each time.

  1. Select your elements in view.
  2. Run Player.
  3. Change view.
  4. Re-select elements.
  5. Run Player.

#5

Thanks, I’ll try it out. I still have the problem with t.GetFailureHandlingOptions() though.
I’ll be back tomorrow.


#6

That just seems like you’re selecting a group and trying to modify a group outside the group editor. You need to make sure you’re selecting the actual text element.


#7

Thanks for the help and the tip about Dynamo Player.
I figured out the reason as to why FilteredElementCollector was returning null for ActiveViews, I guess I had to go inside each viewport per sheet.

I’ll figure out how to do that using the API.