The following graph will load a family from a directory, delete all unused Family and Family Types of a Category, then Save and/or Load the family into the current project.
Here is the core code in the “Open Document & Clean” node:
import System
import clr
clr.AddReference("RevitNodes")
import Revit
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitAPI")
clr.AddReference('DSCoreNodes')
from DSCore import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
currDoc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
paths = IN[0]
if not isinstance(paths, list): paths = [paths]
cats = List.Flatten([IN[1]],1)
save = IN[2]
load = IN[3]
class FamilyOption(IFamilyLoadOptions):
def OnFamilyFound(self, familyInUse, overwriteParameterValues):
overwriteParameterValues = True
return True
def OnSharedFamilyFound(
self, sharedFamily, familyInUse, source, overwriteParameterValues):
source = FamilySource.Family
overwriteParameterValues = True
return True
delIds = []
errorReport = None
try:
for path in paths:
doc = app.OpenDocumentFile(path)
for cat in cats:
trans = Transaction(doc,'del')
trans.Start()
allElements = (FilteredElementCollector(doc).OfClass(FamilySymbol).OfCategory(System.Enum.ToObject(BuiltInCategory, cat.Id)).ToElements())
allFamilyIds = [x.Family.Id for x in allElements]
allTypeIds = [x.Id for x in allElements]
placedElements = (FilteredElementCollector(doc).OfClass(FamilyInstance).OfCategory(System.Enum.ToObject(BuiltInCategory, cat.Id)).WhereElementIsNotElementType().ToElements())
placedElementTypeIds = set([x.get_Parameter(BuiltInParameter.ELEM_TYPE_PARAM).AsElementId() for x in placedElements])
placedElementTypes = [doc.GetElement(x) for x in placedElementTypeIds]
placedFamilyIds = [x.Family.Id for x in placedElementTypes]
diffTypeIds = list(set(allTypeIds).difference(placedElementTypeIds))
diffFamilyIds = list(set(allFamilyIds).difference(placedFamilyIds))
dels = List.Join(diffTypeIds,diffFamilyIds)
delIds.append(dels)
for id in dels:
doc.Delete(id)
trans.Commit()
trans.Dispose()
if load:
doc.LoadFamily(currDoc,FamilyOption())
if save:
opt = SaveAsOptions()
opt.OverwriteExistingFile = True
opt.Compact = True
opt.MaximumBackups = 1
doc.SaveAs(path,opt)
doc.Close(False)
else:
doc.Close(False)
except:
import traceback
errorReport = traceback.format_exc()
if errorReport is None:
OUT = delIds
else:
OUT = errorReport
Thanks go out to @erfajo, @jacob.small, @Konrad_K_Sobon and others!