pyRevit

Code
Library
Offset View CropBox of Selected Viewports
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
from Autodesk.Revit.DB import *
# pyRevit IMPORTS
from pyrevit.forms import alert
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
uidoc = __revit__.ActiveUIDocument
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document
rvt_year = int(app.VersionNumber)
# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║ ║ ║║ ║║║║╚═╗
# ╚ ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ Functions
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
def convert_cm_to_internal(length):
"""Function to convert cm to internal units."""
# RVT >= 2022
if rvt_year < 2022:
from Autodesk.Revit.DB import DisplayUnitType
return UnitUtils.Convert(length,
DisplayUnitType.DUT_CENTIMETERS,
DisplayUnitType.DUT_DECIMAL_FEET)
# RVT >= 2022
else:
from Autodesk.Revit.DB import UnitTypeId
return UnitUtils.ConvertToInternalUnits(length, UnitTypeId.Centimeters)
def get_selected_elements():
"""Property that retrieves selected views or promt user to select some from the dialog box."""
# GET SELECTED ELEMENTS IN UI
selected_elements = [doc.GetElement(el_id) for el_id in uidoc.Selection.GetElementIds()]
return selected_elements
# ╔═╗╔═╗╔╗╔╔╦╗╦═╗╔═╗╦ ╔═╗
# ║ ║ ║║║║ ║ ╠╦╝║ ║║ ╚═╗
# ╚═╝╚═╝╝╚╝ ╩ ╩╚═╚═╝╩═╝╚═╝ CONTROLS
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
__controls__ = """
ADJUST THESE VALUES AS YOU WANT.
You can use Positive, Negative and Zero values"""
TOP = convert_cm_to_internal(0)
BOTTOM = convert_cm_to_internal(-10)
RIGHT = convert_cm_to_internal(0)
LEFT = convert_cm_to_internal(0)
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if __name__ == '__main__':
# GET SELECTED VIEWPORTS
selected = get_selected_elements()
selected_viewports = [i for i in selected if type(i) == Viewport]
# VERIFY THAT VIEWPORTS WERE SELECTED
if not selected_viewports:
alert("No ViewPorts were selected.\nPlease, try again.", exitscript=True)
# START TRANSACTION
with Transaction(doc,__title__) as t:
t.Start()
# LOOP THROUGH SELECTED VIEWPORTS
for vp in selected_viewports:
view.CropBoxActive = True #FIXME This might give an error if View has ScopeBox
# GET VIEW CROPBOX
view_id = vp.ViewId
view = doc.GetElement(view_id)
view_bb = view.CropBox
# CREATE NEW BOUNDING BOX
BB = BoundingBoxXYZ()
BB.Min = XYZ(view_bb.Min.X + LEFT , view_bb.Min.Y + BOTTOM , view_bb.Min.Z)
BB.Max = XYZ(view_bb.Max.X + RIGHT , view_bb.Max.Y + TOP , view_bb.Max.Z)
# APPLY NEW BOUNDING BOX
view.CropBox = BB
t.Commit()

⌨️ Happy Coding!
Erik Frits