Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,46 +1,83 @@
__title__ = "Purge unplaced Views"
__doc__ = "Delete all Views which have not been placed onto Sheets."

import sys

from pyrevit import forms
from pyrevit import revit, DB
from pyrevit.framework import List
from pyrevit.forms import SheetOption, SelectFromList, TemplateListItem

uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document

cl = DB.FilteredElementCollector(doc)

viewports = List[DB.ElementId]\

# name wrapper for forms
class ViewOption(TemplateListItem):
def __init__(self, view_element):
super(ViewOption, self).__init__(view_element)

@property
def name(self):
"""View Name"""
return '{}'.format(revit.query.get_name(doc.GetElement(self.item)))


# custom form to select from a specific list of sheets instead of all sheets in the project
def select_views_to_preserve(title='Select Sheets to preserve',
button_name='Select Views to Keep',
width=600,
multiple=True,
sheets_to_keep=None
):
selected_sheets = SelectFromList.show(
sorted([ViewOption(x) for x in sheets_to_keep],
key=lambda x: x.name),
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True
)

return selected_sheets


viewports = List[DB.ElementId] \
([i.ViewId for i in cl.OfCategory(DB.BuiltInCategory.OST_Viewports).WhereElementIsNotElementType()])

views = List[DB.ElementId]\
([i.Id for i in DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Views).WhereElementIsNotElementType()])
views = List[DB.ElementId] \
([i.Id for i in
DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Views).WhereElementIsNotElementType() if
not i.IsTemplate])

unplaced_views = List[DB.ElementId]([v for v in views if v not in viewports])

message = 'There are {} unplaced Views in the current model. Are you sure you want to delete them?'.format(str(len(unplaced_views)))
message = 'There are {} unplaced Views in the current model. Are you sure you want to delete them?'.format(
str(len(unplaced_views)))

if len(unplaced_views) == 0:
forms.alert("No unpolaced Views, well done!")
forms.alert("No unplaced Views, well done!")
else:
if forms.alert(message, ok=False, yes=True, no=True, exitscript=True):
with revit.Transaction("Delete unplaced Views"):
try:
unplaced_names = [] # Get sheet names
if forms.alert(message, sub_msg="You can select the views to keep. If you select none, all views will be purged.", ok=False, yes=True, no=True, exitscript=True):
excluded_views = select_views_to_preserve(sheets_to_keep=unplaced_views)
if excluded_views is not None:
views_to_purge = List[DB.ElementId]([v for v in unplaced_views if v not in excluded_views])
with revit.Transaction("Delete unplaced Views"):
try:
for view in unplaced_views:
name = doc.GetElement(view).Name
doc.Delete(view) # Delete the sheets
unplaced_names.append(name)
purged_names = [] # Get sheet names
try:
for view in views_to_purge:
name = doc.GetElement(view).Name
doc.Delete(view) # Delete the sheets
purged_names.append(name)
except:
pass
# print result
print("VIEWS DELETED:\n")
for s in purged_names:
print("{}".format(s))
except:
pass
# print result
print("VIEWS DELETED:\n")
for s in unplaced_names:
print("{}".format(s))
except:
forms.alert("Could not execute the script.")




forms.alert("Could not execute the script.")
Original file line number Diff line number Diff line change
@@ -1,35 +1,94 @@
__title__ = "Purge unused sheets"
__doc__ = "Delete all the Sheets without Viewports on them."
__doc__ = "Delete all the Sheets without Viewports or schedules on them."

from pyrevit import forms
from pyrevit import revit, DB
from pyrevit.framework import List
from pyrevit.forms import SheetOption, SelectFromList, TemplateListItem

uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document

cl = DB.FilteredElementCollector(doc)
FEC = DB.FilteredElementCollector
BIP = DB.BuiltInParameter

sheets = List[DB.ElementId]\
([i.Id for i in cl.OfClass(DB.ViewSheet).WhereElementIsNotElementType() if len(i.GetAllViewports()) == 0])

message = 'There are {} empty Sheets in the current model. Are you sure you want to delete them?'.format(str(len(sheets)))
def get_sheet_nr(sheet_element):
return sheet_element.get_Parameter(BIP.SHEET_NUMBER).AsValueString()

if len(sheets) == 0:
forms.alert("No empty Sheets, well done!")
else:
if forms.alert(message, ok=False, yes=True, no=True, exitscript=True):
with revit.Transaction(__title__):
try:
s_names = [doc.GetElement(s).Title for s in sheets] # Get sheet names
doc.Delete(sheets) # Delete the sheets
# print result
print("SHEETS DELETED:\n")
for s in s_names:
print("{}".format(s))
except:
forms.alert("Could not execute the script (make sure there are no active empty Sheets).")

# custom ViewOption wrapper to display Sheet Number + Name
class SheetViewOption(TemplateListItem):
def __init__(self, view_element):
super(SheetViewOption, self).__init__(view_element)

@property
def name(self):
"""Sheet Number + name"""
return '{} - {}'.format(get_sheet_nr(self.item), revit.query.get_name(self.item))


# custom form to select from a specific list of sheets instead of all sheets in the project
def select_sheets_preserve(title='Select Sheets to preserve',
button_name='Select',
width=600,
multiple=True,
sheets_to_keep=None
):
selected_sheets = SelectFromList.show(
sorted([SheetViewOption(x) for x in sheets_to_keep],
key=lambda x: x.name),
title=title,
group_selector_title='Sheet Sets:',
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True
)

return selected_sheets


# get the sheets with no viewports - this does not pick up sheets with schedules
sheets_with_no_views = [i for i in FEC(doc).OfClass(DB.ViewSheet).WhereElementIsNotElementType() if
len(i.GetAllPlacedViews()) == 0]

# get the schedules and sheets that they are placed on
schedules = FEC(doc).OfClass(DB.ScheduleSheetInstance).ToElements()
sheets_with_schedules = set()
for sch in schedules:
if sch.IsTitleblockRevisionSchedule: # Skip revision schedules
continue
owner_id = sch.OwnerViewId
if owner_id != DB.ElementId.InvalidElementId:
sheet = doc.GetElement(owner_id)
if isinstance(sheet, DB.ViewSheet):
sheets_with_schedules.add(sheet.Id) # use Id to be able to compare lists

sheets_with_no_views = [i for i in FEC(doc).OfClass(DB.ViewSheet).WhereElementIsNotElementType() if
len(i.GetAllPlacedViews()) == 0]

# subtract sheets with schedules from the list of sheets with no viewports
unused_sheets = [i for i in sheets_with_no_views if i.Id not in sheets_with_schedules]

if len(unused_sheets) == 0:
forms.alert("No empty Sheets, well done!")
else:
message = 'There are {} empty Sheets in the current model. Do you choose to proceed?'.format(
str(len(unused_sheets)))
if forms.alert(message, sub_msg="You can select the sheets to keep", ok=False, yes=True, no=True, exitscript=True):
excluded_sheets = select_sheets_preserve(sheets_to_keep=unused_sheets)
if excluded_sheets is not None:
sheets_to_purge = List[DB.ElementId]([sh.Id for sh in unused_sheets if sh not in excluded_sheets])
if not sheets_to_purge:
forms.alert("No Sheets deleted.", exitscript=True)
with revit.Transaction(__title__):
try:
s_names = [doc.GetElement(s).Title for s in sheets_to_purge] # Get sheet names
doc.Delete(sheets_to_purge) # Delete the sheets
# print result
print("SHEETS DELETED:\n")
for s in s_names:
print("{}".format(s))
except:
forms.alert("Could not execute the script (make sure there are no active empty Sheets).")