Project parameters refer to those parameters that have been associated with some categories in a particular project model. They are ready to use by the Revit elements which tie to those categories.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
From user perspective, they will show up in the Element Properties dialog if the parameters are designed to be visible; from programmer perspective, they can be accessed from the Parameters collection of the element of interest.
Project parameters really confuse people sometimes. A few questions may come in mind, for example:
Q1. Does each of them map to a BuiltInParameter?
Q2. Are they Shared Parameters?
Q3. Any tie between Project Parameters and Shared Parameters?
Q4. Do they have anything to do with FamilyParameter?
Q5. How are they associated with categories or elements?
Q6. Is there really a Project Parameter thing?
Let us clarify these concepts first.
A1: No. Project parameter has nothing to do with BuiltInParameter. Rather, we can think them as non-built-in parameters. They share some common characters though, the most important of which is both have been associated with certain elements of certain project models through categories.
A2: They could be if seeing from some point of view. As can be seen from the Project Parameters user interface in Revit, Shared Parameters can be bound to the current project model to become Project Parameters. But from the accuracy perspective of view, the answer is NO. Project Parameter does not equal to Shared Parameter. Shared Parameters are like a ware house or a repository for building up some other parameters, not just project parameters, I would say. Another example: FamilyParameter can also be defined from Shared Parameter but we should not mistake one with another either.
A3: If a Project Parameter is defined from a Shared Parameter as mentioned above, some ties such as GUID and Visibility should be still somewhere but it will test our patience and intelligence to seek them. We will elaborate what this exactly means with the assistance of some code examples and use cases later.
A4: No, not at all. I would say they are counterparts though, one of which addresses Project Model and the other Family Model.
A5: Through the BindingMap, ElementBinding, InstanceBinding and TypeBinding. We will demonstrate these in detail with code later.
A6. It depends. From user perspective, the answer is YES. As mentioned a bit earlier, there is a Project Parameters user interface in Revit. However, it is also quite confusing. If the Add sub dialog is opened, two options will be found, one of which is the Project Parameter (Itself?! No recursive/cross reference issue at all?!), and the other is Shared Parameter. From programmer perspective, the answer is NO. There is not a ProjectParameter class in the API, not like the FamilyParameter or Parameter. But we do have a way to find them as mentioned in the A5 and demonstrated in the following code.
Public Class RawProjectParameterInfo
Public Shared Property FileName() As String
Get
Return m_FileName
End Get
Set(ByVal value As String)
m_FileName = Value
End Set
End Property
Private Shared m_FileName As String
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = Value
End Set
End Property
Private m_Name As String
Public Property Group() As BuiltInParameterGroup
Get
Return m_Group
End Get
Set(ByVal value As BuiltInParameterGroup)
m_Group = Value
End Set
End Property
Private m_Group As BuiltInParameterGroup
Public Property Type() As ParameterType
Get
Return m_Type
End Get
Set(ByVal value As ParameterType)
m_Type = Value
End Set
End Property
Private m_Type As ParameterType
Public Property [ReadOnly]() As Boolean
Get
Return m_ReadOnly
End Get
Set(ByVal value As Boolean)
m_ReadOnly = value
End Set
End Property
Private m_ReadOnly As Boolean
Public Property BoundToInstance() As Boolean
Get
Return m_BoundToInstance
End Get
Set(ByVal value As Boolean)
m_BoundToInstance = value
End Set
End Property
Private m_BoundToInstance As Boolean
Public Property BoundCategories() As String()
Get
Return m_BoundCategories
End Get
Set(ByVal value As String())
m_BoundCategories = value
End Set
End Property
Private m_BoundCategories As String()
Public Property FromShared() As Boolean
Get
Return m_FromShared
End Get
Set(ByVal value As Boolean)
m_FromShared = value
End Set
End Property
Private m_FromShared As Boolean
Public Property GUID() As String
Get
Return m_GUID
End Get
Set(ByVal value As String)
m_GUID = value
End Set
End Property
Private m_GUID As String
Public Property Owner() As String
Get
Return m_Owner
End Get
Set(ByVal value As String)
m_Owner = value
End Set
End Property
Private m_Owner As String
Public Property Visible() As Boolean
Get
Return m_Visible
End Get
Set(ByVal value As Boolean)
m_Visible = value
End Set
End Property
Private m_Visible As Boolean
End Class
Public Shared Function RawConvertSetToList(Of T)(ByVal setVar As IEnumerable) As List(Of T)
Dim list As List(Of T) = (From p In setVar Select p)
Return list
End Function
Public Shared Function RawGetProjectParametersInfo(ByVal doc As Document) As List(Of RawProjectParameterInfo)
RawProjectParameterInfo.FileName = doc.Title
Dim paramList As New List(Of RawProjectParameterInfo)()
Dim map As BindingMap = doc.ParameterBindings
Dim it As DefinitionBindingMapIterator = map.ForwardIterator()
it.Reset()
While it.MoveNext()
Dim eleBinding As ElementBinding = TryCast(it.Current, ElementBinding)
Dim insBinding As InstanceBinding = TryCast(eleBinding, InstanceBinding)
Dim def As Definition = it.Key
If def IsNot Nothing Then
Dim extDef As ExternalDefinition = TryCast(def, ExternalDefinition)
Dim sharedVar As Boolean = extDef IsNot Nothing
Dim param As New RawProjectParameterInfo() With { _
.Name = def.Name, _
.Group = def.ParameterGroup, _
.Type = def.ParameterType, _
.ReadOnly = def.IsReadOnly, _
.BoundToInstance = insBinding IsNot Nothing, _
.BoundCategories = RawConvertSetToList(Of Autodesk.Revit.DB.Category)(eleBinding.Categories).Select(Function(c) c.Name).ToArray(), _
.FromShared = sharedVar, _
.GUID = If(sharedVar, extDef.GUID.ToString(), String.Empty), _
.Owner = If(sharedVar, extDef.OwnerGroup.Name, String.Empty), _
.Visible = If(sharedVar, extDef.Visible, True) _
}
paramList.Add(param)
End If
End While
Return paramList
End Function
And the following code will convert the informative object List into a single string:
Public Shared Function RawParametersInfoToCSVString(ByVal infoList As List(Of RawProjectParameterInfo), ByRef title As String) As String
Dim sb As New StringBuilder()
Dim propInfoArray As PropertyInfo() = GetType(RawProjectParameterInfo).GetProperties()
For Each pi As PropertyInfo In propInfoArray
title += pi.Name + ","
Next
title = title.Remove(title.Length - 1)
For Each info As RawProjectParameterInfo In infoList
For Each pi As PropertyInfo In propInfoArray
Dim obj As Object = info.GetType().InvokeMember(pi.Name, BindingFlags.GetProperty, Nothing, info, Nothing)
Dim list As IList = TryCast(obj, IList)
If list IsNot Nothing Then
Dim str As String = String.Empty
For Each e As Object In list
str += e.ToString() & ";"
Next
str = str.Remove(str.Length - 1)
sb.Append(str & ",")
Else
sb.Append((If(obj Is Nothing, String.Empty, obj.ToString())) & ",")
End If
Next
sb.Remove(sb.Length - 1, 1).Append(Environment.NewLine)
Next
Return sb.ToString()
End Function
Then we can write all the project parameter information of a Revit Document to a CSV file.
…
Dim paramsInfo As List(Of RawProjectParameterInfo) = RawGetProjectParametersInfo(CachedDoc)
Using sw As New StreamWriter("c:\temp\ProjectParametersInfo.csv")
Dim title As String = String.Empty
Dim rows As String = RawParametersInfoToCSVString(paramsInfo, title)
sw.WriteLine(title)
sw.Write(rows)
End Using
…
Finally the CSV file can be read into a spreadsheet of Excel.
By the way, here is what the Project Parameters window look like in Revit regarding the particular project model (or the API term Document):
Some keen observers may notice that the Project Parameters window misses one parameter, specifically the ‘Volume42’ one. Good catch! It is because that Project Parameter is defined from an invisible Shared Parameter from the same sample external DefinitionFile that we demonstrated a few times before.
Again, some logical readers will ask why the FromShared column are all False then as obviously some other Project Parameters are defined from Shared Parameters too, besides the ‘Volume42’, such as the ‘Area11’ and the ‘Volume41’. Good catch again! It is because once Shared Parameters are bound to categories, their ExternalDefintion objects cannot be cast back! As mentioned earlier, the Shared Parameter related information should be still somewhere as verified by the fact that the parameter Volume42 is hidden in the dialog!
ProjectParameter Infoer of RevitAddinWizard can help do all of these in a configurable and flexible way either with VB.NET or C# in no time.
Recent Comments