Filtered element collector to get elements of category on view in docs

@Nick_Boyts You are right, the filtered element collector need to use a a view that is within it’s document.

@Mostafa_El_Ayoubi I also found the thread where GetLinkedElement.InHostViewAndCategory was born from:How to collect elements from links visible on a view in the host model? And modified it like so to get it to use lists documents. And changed the VERY SUBTLE “Elev” parameter call to “Elév.” because french. I just combine it with a Select.ByCategoryAndView to get the current document, then AddItemToFront with funny lacing.

As a side note, ElementOwnerViewFilter only considers 2d elements, wish explains my empty lists.

#Copyright (c) mostafa el ayoubi ,  2017
#Data-Shapes www.data-shapes.net , elayoubi.mostafa@gmail.com

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import*
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
import System
from System.Collections.Generic import *

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import*
doc = DocumentManager.Instance.CurrentDBDocument

#Inputs
if isinstance(IN[2],list):
	categories = IN[2]
else:
	categories = [UnwrapElement(IN[2])]
linkdocs = IN[1]
if isinstance(IN[0],list):
	views = UnwrapElement(IN[0])
else:
	views = [UnwrapElement(IN[0])]

collector = []

#getting project base point elevation
basepointfilter = ElementCategoryFilter(BuiltInCategory.OST_ProjectBasePoint)
basepoint = FilteredElementCollector(doc).WherePasses(basepointfilter).ToElements()
bpelevation = [b.ParametersMap.get_Item('Elév.').AsDouble() for b in basepoint]

#Category filter
catfilter = []
for i in categories:
	catfilter.append(ElementCategoryFilter(System.Enum.ToObject(BuiltInCategory, int(str(i.Id)))))

catfilterlist = List[ElementFilter](catfilter)
filter = LogicalOrFilter(catfilterlist)

UIunit = Document.GetUnits(doc).GetFormatOptions(UnitType.UT_Length).DisplayUnits
level = []
for v in views:

	#creating a boundingbox for each view from it's crop box and view range
	bb = v.CropBox
	vr = v.GetViewRange()
	topclip = PlanViewPlane.TopClipPlane
	bottomclip = PlanViewPlane.BottomClipPlane
	cutclip = PlanViewPlane.CutPlane
	toplevel = (doc.GetElement(vr.GetLevelId(topclip)))
	topoffset = vr.GetOffset(topclip)
	cutlevel = (doc.GetElement(vr.GetLevelId(cutclip)))
	cutoffset = vr.GetOffset(cutclip)
	try:
		topZ = toplevel.Elevation + topoffset - bpelevation[0]
	except:
		topZ = cutlevel.Elevation + cutoffset - bpelevation[0]
	bottomlevel = (doc.GetElement(vr.GetLevelId(bottomclip)))
	bottomoffset = vr.GetOffset(bottomclip)
	try:
		bottomZ = bottomlevel.Elevation + bottomoffset - bpelevation[0]
	except :
		bottomZ = cutlevel.Elevation - bpelevation[0]
	min = bb.Min
	max = bb.Max
	newmin = XYZ(min.X,min.Y,bottomZ)
	newmax = XYZ(max.X,max.Y,topZ)
	ol = Outline(newmin,newmax)

	#combining boundingbox and category filters
	bbfilter = BoundingBoxIntersectsFilter(ol)
	andfilter = LogicalAndFilter(filter,bbfilter)

	#collecting elements
	collectordoc = []
	for linkdoc in linkdocs:
		collectordoc.append(FilteredElementCollector(linkdoc).WherePasses(andfilter).ToElements())
	collector.append(collectordoc)

OUT = collector
5 Likes