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 tied in with those categories. 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 elements of interest.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
Project parameters really confuse people sometimes. A few questions may come in mind, for example:
1. Does each of them map to a BuiltInParameter?
2. Are they Shared Parameters?
3. Any tie between Project Parameters and Shared Parameters?
4. Do they have anything to do with FamilyParameter?
5. How are they associated with categories or elements?
6. Is there really a Project Parameter thing?
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 of them have been associated with certain elements of certain project models through categories.
A2: They could be if seen 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 point 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, I would say. Another example: FamilyParameter can also be defined from Shared Parameter but we should not mistake one with another either in this case.
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, YES. As mentioned a bit earlier, there is a Project Parameters interface in Revit. However, it’s also 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 issues at all?!), and the other is Shared Parameter. From programmer perspective, NO. There is not a ProjectParameter class in the API, not like 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 static string FileName { get; set; }
public string Name { get; set; }
public BuiltInParameterGroup Group { get; set; }
public ParameterType Type { get; set; }
public bool ReadOnly { get; set; }
public bool BoundToInstance { get; set; }
public string[] BoundCategories { get; set; }
public bool FromShared { get; set; }
public string GUID { get; set; }
public string Owner { get; set; }
public bool Visible { get; set; }
}
public static List<T> RawConvertSetToList<T>(IEnumerable set)
{
List<T> list = (from T p in set select p).ToList<T>();
return list;
}
public static List<RawProjectParameterInfo> RawGetProjectParametersInfo(Document doc)
{
RawProjectParameterInfo.FileName = doc.Title;
List<RawProjectParameterInfo> paramList = new List<RawProjectParameterInfo>();
BindingMap map = doc.ParameterBindings;
DefinitionBindingMapIterator it = map.ForwardIterator();
it.Reset();
while (it.MoveNext())
{
ElementBinding eleBinding = it.Current as ElementBinding;
InstanceBinding insBinding = eleBinding as InstanceBinding;
Definition def = it.Key;
if (def != null )
{
ExternalDefinition extDef = def as ExternalDefinition;
bool shared = extDef != null;
RawProjectParameterInfo param = new RawProjectParameterInfo
{
Name = def.Name,
Group = def.ParameterGroup,
Type = def.ParameterType,
ReadOnly = def.IsReadOnly,
BoundToInstance = insBinding!=null,
BoundCategories = RawConvertSetToList<Category>(eleBinding.Categories).Select(c=>c.Name).ToArray(),
FromShared = shared,
GUID = shared ? extDef.GUID.ToString() : string.Empty,
Owner = shared ? extDef.OwnerGroup.Name : string.Empty,
Visible = shared ? extDef.Visible : true,
};
paramList.Add(param);
}
}
return paramList;
}
And the following code will convert the informative object List into a single string:
public static string RawParametersInfoToCSVString(List<RawProjectParameterInfo> infoList, ref string title)
{
StringBuilder sb = new StringBuilder();
PropertyInfo[] propInfoArray = typeof(RawProjectParameterInfo).GetProperties();
foreach (PropertyInfo pi in propInfoArray)
{
title += pi.Name + ",";
}
title = title.Remove(title.Length - 1);
foreach (RawProjectParameterInfo info in infoList)
{
foreach (PropertyInfo pi in propInfoArray)
{
object obj = info.GetType().InvokeMember(pi.Name, BindingFlags.GetProperty, null, info, null);
IList list = obj as IList;
if (list != null)
{
string str = string.Empty;
foreach (object e in list)
{
str += e.ToString() + ";";
}
str = str.Remove(str.Length - 1);
sb.Append(str + ",");
}
else
{
sb.Append((obj == null ? string.Empty : obj.ToString()) + ",");
}
}
sb.Remove(sb.Length - 1, 1).Append(Environment.NewLine);
}
return sb.ToString();
}
Then we can write all the project parameter information of a Revit Document to a CSV file.
…
List<RawProjectParameterInfo> paramsInfo = RawGetProjectParametersInfo(CachedDoc);
using (StreamWriter sw = new StreamWriter(@"c:\temp\ProjectParametersInfo.csv"))
{
string title = string.Empty;
string rows = RawParametersInfoToCSVString(paramsInfo, ref title);
sw.WriteLine(title);
sw.Write(rows);
}
…
Finally the CSV file can be read into a spreadsheet of Excel.
By the way, here is what the Project Parameters window looks like in Revit regarding the particular project model:
Some keen observers may notice that the Project Parameters window misses one parameter, the ‘Volume42’ one. Good catch! It is because the 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 anymore! 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 in no time.
Recent Comments