Here an updated code for ViewPlans and SectionViews
Python Code (compatible all engines)
Edit 25/04/2024 : code updated → add input list view
import clr
import sys
import System
from System.Collections.Generic import List
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
def gen_PairPts(*args):
"""generator for point pair loop
"""
for idx, pt in enumerate(args):
try: yield pt, args[idx + 1]
except : yield pt, args[0]
def solid_fromBBX(bbox):
pt0 = XYZ( bbox.Min.X, bbox.Min.Y, bbox.Min.Z )
pt1 = XYZ( bbox.Max.X, bbox.Min.Y, bbox.Min.Z )
pt2 = XYZ( bbox.Max.X, bbox.Max.Y, bbox.Min.Z )
pt3 = XYZ( bbox.Min.X, bbox.Max.Y, bbox.Min.Z )
#create generator
pairPts = gen_PairPts(pt0, pt1, pt2, pt3)
#Create loop, still in BBox coords
edges = List[Curve]()
for pt1, pt2 in pairPts:
edges.Add(Line.CreateBound( pt1, pt2 ))
height = bbox.Max.Z - bbox.Min.Z
baseLoop = CurveLoop.Create( edges )
loopList = List[CurveLoop]()
loopList.Add( baseLoop )
preTransformBox = GeometryCreationUtilities.CreateExtrusionGeometry( loopList, XYZ.BasisZ, height )
transformBox = SolidUtils.CreateTransformed( preTransformBox, bbox.Transform )
return transformBox
def toList(x):
if isinstance(x, (list, dict)) or \
(hasattr(x, "GetType") and x.GetType().GetInterface("ICollection") is not None):
return x
else : return [x]
lst_View = toList(UnwrapElement(IN[0]))
catList = toList(UnwrapElement(IN[1]))
catBiplst = [ System.Enum.ToObject(BuiltInCategory, int(x.Id.ToString()) ) for x in catList]
linkInstances = FilteredElementCollector(doc).OfClass(DB.RevitLinkInstance)
out = []
for view_ in lst_View:
temp = []
if view_.ViewType == ViewType.Section:
for lnkInstance in linkInstances:
lnk_doc = lnkInstance.GetLinkDocument()
transf = lnkInstance.GetTotalTransform()
bbxView = view_.CropBox
solidbbx = solid_fromBBX(bbxView)
# apply link instance transform and create Filters (Solid + Categories)
solidbbx = DB.SolidUtils.CreateTransformed(solidbbx, transf.Inverse)
filterSolid = ElementIntersectsSolidFilter(solidbbx)
cats = List[BuiltInCategory](catBiplst)
filtercat = ElementMulticategoryFilter(cats)
elemIntersect = FilteredElementCollector(lnk_doc).WherePasses(filterSolid).WherePasses(filtercat).WhereElementIsNotElementType().ToElements()
# FOR DEBUG
#out.append([lnkInstance.Name, elemIntersect, solidbbx.ToProtoType()])
temp.append([lnkInstance.Name, elemIntersect])
elif view_.ViewType in [ViewType.CeilingPlan, ViewType.FloorPlan]:
#get bootom and top Elevation of active viewrange
viewRange = view_.GetViewRange()
topClipPlaneId = viewRange.GetLevelId(PlanViewPlane.TopClipPlane)
topClipPlane = doc.GetElement(topClipPlaneId)
topOffset = viewRange.GetOffset(PlanViewPlane.TopClipPlane)
bttmClipPlaneId = viewRange.GetLevelId(PlanViewPlane.BottomClipPlane)
bttmClipPlane = doc.GetElement(bttmClipPlaneId)
bttmOffset = viewRange.GetOffset(PlanViewPlane.BottomClipPlane)
for lnkInstance in linkInstances:
lnk_doc = lnkInstance.GetLinkDocument()
transf = lnkInstance.GetTotalTransform()
# get min and max from active ViewRange
bbxActView = view_.CropBox
bbxActView.Min = XYZ(bbxActView.Min.X, bbxActView.Min.Y, bttmClipPlane.ProjectElevation + bttmOffset)
bbxActView.Max = XYZ(bbxActView.Max.X, bbxActView.Max.Y, topClipPlane.ProjectElevation + topOffset)
bbxActView.Transform = transf.Inverse
# create Solid Filter
solidbbx = solid_fromBBX(bbxActView)
filterSolid = ElementIntersectsSolidFilter(solidbbx)
# create categories filter
cats = List[BuiltInCategory](catBiplst)
filtercat = ElementMulticategoryFilter(cats)
elemIntersect = FilteredElementCollector(lnk_doc).WherePasses(filterSolid).WherePasses(filtercat).WhereElementIsNotElementType().ToElements()
# FOR DEBUG
#out.append([lnkInstance.Name, elemIntersect, solidbbx.ToProtoType(), bbxActView.Min.ToPoint(), bbxActView.Max.ToPoint()])
temp.append([lnkInstance.Name, elemIntersect])
out.append([view_, temp])
OUT = out