By Carol Gitonga
Many Revit developers often work on extensive projects that require the use of multiple separate Revit files. In such cases, the need arises to link these models together for efficiency and convenience. This is where Revit Links come into play, providing interoperability by allowing the linking of several Revit models into a single working file.
The Revit API offers a set of classes and methods to achieve this functionality. The RevitLinkType
class represents another Revit document ("link") brought into the current one ("host"), while the RevitLinkInstance
class represents an instance of a RevitLinkType
.
To create new links programmatically, the RevitLinkType.Create()
method is employed. This method is used to create a new Revit link type and load the linked document. It requires the host document, a model path to the file to be linked (which can be a path on the local disk, Revit Server, or the Cloud and must be a full path), and a RevitLinkOptions
object.
The RevitLinkOptions
class represents options for creating and loading a Revit link. These options may include whether Revit will store a relative or absolute path to the linked file and the workset configuration.
Once the linked document is loaded, the RevitLinkInstance.Create()
method is used to place an instance of the link in the model.
Below is an example using RevitLinkType.Create()
, with the variable pathName
representing the full path to the file on disk to be linked.
public ElementId CreateRevitLink(Document doc, string pathName)
{
FilePath path = new FilePath(pathName);
RevitLinkOptions options = new RevitLinkOptions(false);
// Create new revit link storing absolute path to file
LinkLoadResult result = RevitLinkType.Create(doc, path, options);
return (result.ElementId);
}
The resulting return value for successfully creating and loading a linked document is a LinkLoadResult
object that stores the outcomes of attempting to load a single linked model. The LinkLoadResult
provides a wide range of methods that you can use to gather more information about the loaded Revit link. In our case, from the code snippet above, we use:
result.ElementId
This retrieves the ElementId
of the loaded Revit Link.
Upon successfully creating the Revit Link, instances can now be added to the document. It's important to note that until a RevitLinkInstance
is created, the Revit link will appear in the Manage Links window, but the elements of the linked file will not be visible in any views.
The code snippet below demonstrates how to create new Revit Link instances. In this case, linkTypeId is the ElementId of the loaded Revit Link from the previous code snippet for creating the Revit Link:
public void CreateLinkInstances(Document doc, ElementId linkTypeId)
{
// Create revit link instance at origin
RevitLinkInstance.Create(doc, linkTypeId);
RevitLinkInstance instance2 = RevitLinkInstance.Create(doc, linkTypeId);
// Offset second instance by 100 feet
Location location = instance2.Location;
location.Move(new XYZ(0, -100, 0));
}
Two instances of RevitLinkType
are created, with the second instance offset by 100 feet. It's important to note that instances will be placed origin-to-origin, and this function cannot be used to create instances of nested links.
Referring to a post in the Revit API forum: https://thebuildingcoder.typepad.com/blog/2008/12/linked-files.html by community member Andrea Tassera, and incorporating contributions from fellow members, below is a complete working sample demonstrating how to load your Revit link for file browsing and add Revit Link instances.
using System;
using System.IO;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using System.Windows.Forms;
namespace RevitLinking
{
[Transaction(TransactionMode.Manual)]
public class Class1:IExternalCommand
{
public Result Execute(ExternalCommandData commandData,
ref string message, ElementSet elements)
{
// Get application and document objects
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
Document doc = uidoc.Document;
try
{
using (Transaction transaction = new Transaction(doc))
{
// Link files in folder
transaction.Start("Link files");
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = (@"C:\");
openFileDialog1.Filter = "RVT|*.rvt";
openFileDialog1.Multiselect = true;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
foreach (string path in openFileDialog1.FileNames)
{
FileInfo filePath = new FileInfo(path);
// debug ***********
MessageBox.Show("filePath.FullName.ToString() = "
+ filePath.FullName.ToString());
// debug ***********
ModelPath linkpath = ModelPathUtils.
ConvertUserVisiblePathToModelPath(filePath.FullName.ToString());
RevitLinkOptions options = new RevitLinkOptions(false);
LinkLoadResult result = RevitLinkType.Create(doc, linkpath, options);
RevitLinkInstance.Create(doc, result.ElementId);
}
}
// Assuming that everything went right return Result.Succeeded
transaction.Commit();
}
return Result.Succeeded;
}
catch (Exception ex)
{
// If something went wrong return Result.Failed
Console.WriteLine("There was a problem!");
Console.WriteLine(ex.Message);
return Result.Failed;
}
}
}
}
Below are valuable sources for developers working with the Revit API and dealing with linked files. Here are the references formatted for clarity:
- Autodesk Revit API Developers Guide - Advanced Topics: Linked Files - Link
- Autodesk Revit API Forum Post on adding Revit Links with C# - Link
- The Building Coder Blog Post on Linked Files (by Jeremy Tammik) - Link
These references provide additional insights, examples, and discussions that can be beneficial for developers working with Revit and the Revit API.