Q: Would be possible to create a tool that would “Transfer View Types” from one project to another?
Background: View Types have a couple of key properties, an assigned View Template, and if new view instances created from the Type should be dependent on the View Template. But the Revit UI does not allow view types to be transferred between projects.
A: Good news! With the API it is possible to determine the View Types defined in a project, read their associated parameters, create new View Types in a second Project, and set these parameters to match the values in the source project.
public void CopyViewTypes()
{
Application app = this.Application;
// source document is the active document
Document sourceDoc = this.ActiveUIDocument.Document;
// target document is an open file named "target.rvt"
Document targetDoc = app.Documents.Cast<Document>().Where(q => Path.GetFileName(q.PathName) == "target.rvt").FirstOrDefault();
// element ids for all instances of the ViewFamilyType class
ICollection<ElementId> viewFamilyTypeIds = new FilteredElementCollector(sourceDoc).OfClass(typeof(ViewFamilyType)).ToElementIds();
// element ids of the view templates used in View Types
ICollection<ElementId> templateIds = new List<ElementId>();
// list of pairs of strings - first item in each pair will be the name of the View Type - second item will be the name of the View Template used by that View Type
IList<Tuple<string, string>> ssList = new List<Tuple<string, string>>();
foreach (ViewFamilyType vft in new FilteredElementCollector(sourceDoc).OfClass(typeof(ViewFamilyType)))
{
// element id of the view template used in this View Type
ElementId defaultTemplateId = vft.get_Parameter(BuiltInParameter.DEFAULT_VIEW_TEMPLATE).AsElementId();
// go to the next View Type if there is no View Template assigned to this view type
if (defaultTemplateId == ElementId.InvalidElementId)
continue;
templateIds.Add(defaultTemplateId);
ssList.Add(new Tuple<string, string>(vft.Name, sourceDoc.GetElement(defaultTemplateId).Name));
}
CopyPasteOptions options = new CopyPasteOptions();
using (Transaction t = new Transaction(targetDoc, "Copy View Types"))
{
t.Start();
// copy the view templates
ElementTransformUtils.CopyElements(sourceDoc, templateIds, targetDoc, Transform.Identity, options);
// copy the view types
ElementTransformUtils.CopyElements(sourceDoc, viewFamilyTypeIds, targetDoc, Transform.Identity, options);
foreach (Tuple<string, string> tup in ssList)
{
Element vft = new FilteredElementCollector(targetDoc).OfClass(typeof(ViewFamilyType)).Where(q => q.Name == tup.Item1).FirstOrDefault();
View template = new FilteredElementCollector(targetDoc).OfClass(typeof(View)).Cast<View>().Where(q => q.IsTemplate && q.Name == tup.Item2).FirstOrDefault();
// assign the view template to the view type
vft.get_Parameter(BuiltInParameter.DEFAULT_VIEW_TEMPLATE).Set(template.Id);
}
t.Commit();
}
}