Create an empty Revit model, and use the API to list all elements in the model. Save this list, and then add to your model the element/item/object/feature you're interested in - in this case a filter. Now once again produce a full element list using the API.
The difference between your second list and your first list will enable you to identify your element by id. Then, armed with this information you can delve further by listing its parameters.
For a filter I found this:
ELEM_CATEGORY_PARAM_MT Category ElementId read-only -1
ELEM_CATEGORY_PARAM Category ElementId read-only -1
DESIGN_OPTION_ID Design Option ElementId read-only -1
PHASE_DEMOLISHED Phase Demolished ElementId read-write -1
PHASE_CREATED Phase Created ElementId read-write -1
ELEMENT_LOCKED_PARAM Locked Integer read-write 0
ELEM_DELETABLE_IN_FAMILY Deletable Integer read-write 1
UNIFORMAT_DESCRIPTION Assembly Description String read-only
UNIFORMAT_CODE Assembly Code String read-write
ID_PARAM Id ElementId read-only Symbol 'Filter 1' 123245
EDITED_BY Edited by String read-only
ELEM_PARTITION_PARAM Workset Integer read-write 0
ELEM_FAMILY_AND_TYPE_PARAM Family and Type ElementId read-only -1
ELEM_FAMILY_PARAM Family ElementId read-only -1
ELEM_TYPE_PARAM Type ElementId read-only -1
SYMBOL_FAMILY_AND_TYPE_NAMES_PARAM Family and Type String read-only Filters: Filter 1
SYMBOL_FAMILY_NAME_PARAM Family Name String read-only Filters
SYMBOL_FAMILY_NAME_PARAM Family Name String read-only Filters
SYMBOL_NAME_PARAM Type Name String read-only Filter 1
SYMBOL_NAME_PARAM Type Name String read-only Filter 1
SYMBOL_ID_PARAM Type Id ElementId read-only -1
So, to identify filters in your model you can use the SYMBOL_FAMILY_NAME_PARAM like below. Iterate through all elements, check the SYMBOL_FAMILY_NAME_PARAM value, and where it is 'Filters', then you have found a filter:
Dim elementIterator As Autodesk.Revit.ElementIterator elementIterator = revitApp.ActiveDocument.Elements While (elementIterator.MoveNext()) 'filters are a symbol, so start here, 'rather than paramcheck every element If TypeOf elementIterator.Current Is Autodesk.Revit.Symbol Then Dim symbol As Autodesk.Revit.Symbol = elementIterator.Current ' then test SYMBOL_FAMILY_NAME_PARAM for 'Filters'. If ParameterChecker(symbol, "testCondition", "SYMBOL_FAMILY_NAME_PARAM", "Filters") Then 'we have found a filter! MessageBox.Show(symbol.Id.Value) MessageBox.Show(symbol.Name) End If End If End While
The function ParameterChecker looks like below. I adapted this from the Revit API intro to perform three different functions. 'testCondition' tests a named paramater for a specified value and returns true or false. 'getValue' returns the value of a named parameter. 'fullReport' lists all parameters and values for a named element.
Public Shared Function ParameterChecker(ByVal elem As Autodesk.Revit.Element, ByVal task As String, ByVal paramName As String, Optional ByVal value As String = "") Dim _ParamEnums As New ArrayList Dim _ParamTypes As New ArrayList Dim _ParamValues As New ArrayList ' Takes some time, so change cursor Dim oldCursor As Cursor = Cursor.Current Cursor.Current = Cursors.WaitCursor Dim fis() As System.Reflection.FieldInfo = GetType(BuiltInParameter).GetFields For Each fi As System.Reflection.FieldInfo In fis ' See if this is an enum (a literal value set at compile time) If fi.IsLiteral Then Try Dim enumInt As Integer = CType(fi.GetValue(Nothing), Integer) Dim enumBip As BuiltInParameter = enumInt Dim param As Parameter = elem.Parameter(enumBip) If Not (param Is Nothing) Then ' this check is much faster than throwing an exception for each invalid param! Select Case param.StorageType Case StorageType.Double _ParamValues.Add(param.AsDouble.ToString) _ParamEnums.Add(fi.Name) _ParamTypes.Add("Double") Case StorageType.Integer _ParamValues.Add(param.AsInteger.ToString) _ParamEnums.Add(fi.Name) _ParamTypes.Add("Integer") Case StorageType.String _ParamValues.Add(param.AsString) _ParamEnums.Add(fi.Name) _ParamTypes.Add("String") Case StorageType.ElementId _ParamValues.Add(param.AsElementId.Value.ToString) _ParamEnums.Add(fi.Name) _ParamTypes.Add("Id") Case StorageType.None ' nothing Case Else ' nothing End Select End If Catch ex As Exception End Try End If 'isLiteral Next fi ' looping field infos ' Revert the cursor Cursor.Current = oldCursor 'KIS for now - in future may display in an user-friendly form... Dim msg As String = "Number of valid Params = " & _ParamEnums.Count & ", " & _ParamTypes.Count & ", " & _ParamValues.Count 'Debug.Print(msg) msg = "Valid Params for this element: " Dim iNum As Integer = _ParamValues.Count For i As Integer = 0 To iNum - 1 msg += vbCrLf & " " & _ParamEnums(i) & ", " & _ParamTypes(i) & ": " & _ParamValues(i) If task = "testCondition" Then If _ParamEnums(i) = paramName And _ParamValues(i) = value Then 'Debug.Print(msg) Return True End If ElseIf task = "getValue" Then If _ParamEnums(i) = paramName Then Return _ParamValues(i) End If ElseIf task = "fullReport" Then WriteOutput(vbCrLf & " " & _ParamEnums(i) & ", " & _ParamTypes(i) & ": " & _ParamValues(i)) End If Next End Function
So this is how you might identify if a model has filters applied, and you can get the name of the filter too. But for me this isn't enough, as I want to know what categories are included and what its rules are.
Its now on the API wish-list as PR #154826 [API wish: API access to filters in Revit model] :)
No comments:
Post a Comment
Comments are moderated, so you'll have to wait a little bit before they appear!