#RTCEUR Wish 3 – Copy View Types & Templates btw Documents

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();
    }
}
Advertisements

4 thoughts on “#RTCEUR Wish 3 – Copy View Types & Templates btw Documents

  1. I am having problems getting this to work. I have two projects open. The project with the View Types and a ‘new’ project without the View Types. When I try to run the Macro I get the following message inside of Revit:

    Revit Failed to execute CopyViewTypes.

    A problem has been detected.

    Autodesk.Revit.Exceptions.ArgumentNullException: The input argument “document” of function
    ‘anonymous-namespace’::Transaction_constructor or one item in the collection is null at line 112 of file
    n:\build\2014_ship_x64_inst_20130709_..\APIUndoTransaction.cpp.
    Parameter name: document
    at MacroModule.execureMacro_(MacroModule*, AString* macroName)
    at MacroModule.executeMacro(MacroModule*, AString* )
    at
    UIMacroGeneralManager.runmacro(UIMacroGeneralManager* , MacroModule* pModule, AString* macroName)

    When I am in the Script Editor, there are no errors.
    Maybe I am doing something wrong?

    • Is targetDoc null? Is there a file “target.rvt” open but not the active document in the current session of Revit?

      Document targetDoc = app.Documents.Cast().Where(q => Path.GetFileName(q.PathName) == “target.rvt”).FirstOrDefault();

      If that is null, then this line would produce an error like the one you are getting.

      Transaction t = new Transaction(targetDoc, “Copy View Types”)

      • Matthew pointed out to me right after I posted the comment that the target.rvt was hard coded. I swapped that for the proper file name and worked like a charm! Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s