It’s seem related to the Element binding process
2 ways to solve:
- use Dynamo Player
- close and re-open the dyn file in Dynamo UI
see here
It’s seem related to the Element binding process
2 ways to solve:
see here
Hi @PiotrB
The code work only for FloorPlan, I’ll look when I have a little more time, but you can get inspiration from this code
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
Hey, your Python code works for a single view. When it got a list o views there is an error:
You’ll need to append a loop into the code. something like for view in views:
and then offset the rest of the actions in that section below it.
code upaded in previous post
try to implement an Exception Handling with try except
to identify the view cause error and check the view limits
I’ve checked that the issue is because of linked but not loaded Revit files, but don’t know how to fix the issue.
If the file are not loaded you cannot access the stuff therein. Force the reload before you start.
I don’t want to access elements in not loaded links, there are some other linked models loaded that I’d like to access. I meant the python code doesn’t work is there are any not loaded links.
Right - the way things are structured you cannot access things in link B if link A isn’t loaded. So ensure that links A to Z are loaded before you start accessing things in link B.
Alternatively you’ll have to find an alternative way to structure the Python above to pass over links which aren’t loaded without throwing the error.