Filtered Element collector using workset

Hi all,
I am trying to extract all elements of a workset from a linked model. I managed to get a list of elements but I also get some elements that doesn’t make sense to have (like sketch plane,Legend component etc…)

here is the modified script from geniusloci

#Alban de Chasteigner 2020
#twitter : @geniusloci_bim
#geniusloci.bim@gmail.com

import clr
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = IN[1]
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

worksets = IN[0] if isinstance(IN[0],list) else [IN[0]]
worksetList = []

for workset in worksets :
	if isinstance(workset,Autodesk.Revit.DB.Workset):
		wks = workset
	else:
		userWorksets = FilteredWorksetCollector(doc).OfKind(WorksetKind.UserWorkset).ToWorksets()
		wks=next((ws for ws in userWorksets if ws.Name.lower() == workset.lower()), None)
	Worksetfilter=ElementWorksetFilter(wks.Id,False)
	#InstanceFilter = ElementClassFilter((FamilyInstance))
	worksetList.append(FilteredElementCollector(doc).WherePasses(Worksetfilter).WhereElementIsNotElementType().WhereElementIsViewIndependent().ToElements())
	

if isinstance(IN[0], list): OUT = worksetList
else: OUT = worksetList[0]

how do I alter the filtered element collector to get rid of the categories like sketch plane,Legend components, automatic dimensions, etc…

ALso, I tried using OfClass filter passing FamilyInstance but, fails to output some elements like grids from some reason.

You could try making a new 3d view, and run the filtered element collector on that. The new view won’t have any legend components, automatic dimensions won’t be exposed, and the like. I don’t think sketch planes will be selected either.

It might also be faster overall to make the view and hide all worksets except the one(s) you want to select elements on, rather than using the ‘passes’ filter in addition to the view filter.

Hi @jacob.small , Thanks for your reply,as I mentioned on the post ,I am trying to run the script on a host model to extract information from the linked files and hence may not be feasible to commit a transaction on the linked model , also it could be very hard to open them in background to add a view as the files are on BIM 360.
Can you also clarify what “WhereElementIsViewIndependent()” does in the script ,I was thinking that it filters out any items that are view dependent like the legend components.

Hi,
you can try to create a filter by combine several properties

here an example

import sys
import clr
import System
from System.Collections.Generic import List
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = IN[1]
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

worksets = IN[0] if isinstance(IN[0],list) else [IN[0]]
worksetList = []

def is_model(e):
	if e.Category is not None and not isinstance(e, SpatialElement):
		if e.Category.CategoryType == CategoryType.Model:
			bbx = e.get_BoundingBox(None)
			if bbx is not None and abs(bbx.Min.Z - bbx.Max.Z) > 0.01:
				return True
	return False

for workset in worksets :
	if isinstance(workset,Autodesk.Revit.DB.Workset):
		wks = workset
	else:
		userWorksets = FilteredWorksetCollector(doc).OfKind(WorksetKind.UserWorkset).ToWorksets()
		wks=next((ws for ws in userWorksets if ws.Name.lower() == workset.lower()), None)
	Worksetfilter=ElementWorksetFilter(wks.Id,False)
	#
	filterCategoryType = System.Predicate[System.Object](is_model)
	worksetList.append(FilteredElementCollector(doc).WherePasses(Worksetfilter).WhereElementIsNotElementType().ToElements().FindAll(filterCategoryType))
	

if isinstance(IN[0], list): OUT = worksetList
else: OUT = worksetList[0]
2 Likes

Brilliant, Thanks I never knew that was a property called “CategoryType”. I will try this out.

1 Like