RevitAPI: Get Cropbox id with Python.

A snippet of a function to get crop box id from a given view.

Tags:  Revit API
Dec 2020

First Method: FilteredElementCollector().Excluding()

Basically, the first method is quite straight forward and goes like this:

You hide your cropbox and with FilteredElementCollector(doc, view_id) we get all visible elements in the given view. Then we have to unhide the cropbox and again with the FilteredElementCollector(doc, view_id) get all elements in the view, but this time we will filter out all elements that we got the first time with .Excluding(element_ids) method, which will get us a single element - cropbox. And then we just have to extract an element id from the collector.

code
def GetViewCropBoxElement(view):
    """Function to get a cropbox_id from the given view."""

    tGroup = TransactionGroup(doc, "Py: Get cropbox_id")
    tGroup.Start()

    trans1 = Transaction(doc, "temp")
    trans1.Start()
    view.CropBoxVisible = False
    trans1.Commit()

    shown_elements_ids= FilteredElementCollector(doc, view.Id).ToElementIds()

    trans1.Start()
    view.CropBoxVisible = True
    trans1.Commit()

    cropbox_id= FilteredElementCollector(doc, view.Id).Excluding(shown_elements_ids).FirstElementId()
    
    tGroup.RollBack()

    return cropbox_id

This method is quite a messy one because of multiple transactions. I encountered issues with this method when I needed to get a cropbox id while I had already been in an open transaction and I didn't want to close it. I have found another solution that worked great for me (method 2 below).


Second Method: FilteredElementCollector().WherePasses(filter)

I have found an article by Jeremy Tammik - "Efficiently Retrieve Crop Box for Given View" of the following snippet in C# and I have just translated it to python for people who don't "speak" C# well enough. I encourage you to read his article to better understand the logic behind this function.

Be aware that FilteredElementCollector will grab cropbox and view so you better exclude view in your code so it does not return false element id.

code
def get_cropbox_id(view):
    """Function to get cropbox_id of a given view."""
    provider = ParameterValueProvider(ElementId( int(BuiltInParameter.ID_PARAM)) )
    rule = FilterElementIdRule(provider, FilterNumericEquals(), view.Id)
    param_filter = ElementParameterFilter(rule)
    collector = FilteredElementCollector(doc).WherePasses(param_filter).ToElementIds()
    if collector:
        for id in collector:
            if id != view.Id:
                return id
    return None