Efficiently Retrieve Crop Box for Given View
Originally Published inKonrads Samulis shared a very nice solution to retrieve the crop box for a given view using a highly efficient parameter filter in his comment on rotating a plan view.
In his own words:
In digging up this old thread, I found something quite curious in the API in 18.1, that I’m not sure was there before.
The method of using a temporary transaction (with rollback) to find the element id of the crop box was taking a very long time on a large model, so I did a bit of digging to see how I could improve it.
I noticed that in the built-in parameter ID_PARAM
of the crop box contains the element id of the view it’s in. E.g., the crop box ‘points’ to the id of the view it is in using ID_PARAM
.
That got me thinking… why not use a parameter filter to retrieve it?
So… in VB.NET (because I’m an old school vber):
Public Function GetELementIDOfCropBox(activeView As View, revDoc As Document) As ElementId
Dim provider As ParameterValueProvider = New ParameterValueProvider(New ElementId(CInt(BuiltInParameter.ID_PARAM)))
Dim ruleID_PARAM As FilterElementIdRule = New FilterElementIdRule(provider, New FilterNumericEquals(), activeView.Id)
Dim filter As ElementParameterFilter = New ElementParameterFilter(ruleID_PARAM)
Dim collector = New FilteredElementCollector(revDoc).WherePasses(filter).ToElementIds().Except(New List(Of ElementId)(New ElementId() {activeView.Id}))
Return collector.FirstOrDefault
End Function
This can all be stuffed into one single statement:
Public Function GetELementIDOfCropBoxShortened(activeView As View, revDoc As Document) As ElementId
Return New FilteredElementCollector(revDoc)
.WherePasses(New ElementParameterFilter(
New FilterElementIdRule(
New ParameterValueProvider(
New ElementId(CInt(BuiltInParameter.ID_PARAM))),
New FilterNumericEquals(),
activeView.Id)))
.ToElementIds()
.Except(New List(Of ElementId)(New ElementId() {activeView.Id})).FirstOrDefault
End Function
Much like your original, I had to exclude the element id of the view, as it also returns its own id from ID_PARAM
.
Hope that this may help someone – I’m sure the Dynamo people who come here for inspiration will want to know this as well…
Many thanks to Konrads for sharing this nice efficient solution!
I ported it to C# and added it to The Building Coder Samples ↗ release 2018.0.135.2 ↗ and the extensive collection of filtered element examples in the module CmdCollectorPerformance.cs ↗:
/// <summary>
/// Return element id of crop box for a given view.
/// The built-in parameter ID_PARAM of the crop box
/// contains the element id of the view it is used in;
/// e.g., the crop box 'points' to the view using it
/// via ID_PARAM. Therefore, we can use a parameter
/// filter to retrieve all crop boxes with the
/// view's element id in that parameter.
/// </summary>
ElementId GetCropBoxFor( View view )
{
ParameterValueProvider provider
= new ParameterValueProvider( new ElementId(
(int) BuiltInParameter.ID_PARAM ) );
FilterElementIdRule rule
= new FilterElementIdRule( provider,
new FilterNumericEquals(), view.Id );
ElementParameterFilter filter
= new ElementParameterFilter( rule );
return new FilteredElementCollector( view.Document )
.WherePasses( filter )
.ToElementIds()
.Where<ElementId>( a => a.IntegerValue
!= view.Id.IntegerValue )
.FirstOrDefault<ElementId>();
}