Analytical Links

Analytical Links

An analytical link is an element connecting 2 separate analytical nodes, which has properties such as fixity state. Analytical links can be created automatically by Revit from analytical beams to analytical columns during modeling based on certain rules. And they can also be created manually, both in the Revit UI and using the Revit API.

In the Revit API, an analytical link is represented by the AnalyticalLink class. Fixity values are available from its associated AnalyticalLinkType.

The example below demonstrates how to read all of the AnalyticalLinks in the document and displays a TaskDialog summarizing the number of automatically generated and manually created AnalyticalLinks.

Code Region: Reading AnalyticalLinks

public void ReadAnalyticalLinks(Document document)
{
    FilteredElementCollector collectorAnalyticalLinks = new FilteredElementCollector(document);
    collectorAnalyticalLinks.OfClass(typeof(AnalyticalLink));

    IEnumerable<AnalyticalLink> alinks = collectorAnalyticalLinks.ToElements().Cast<AnalyticalLink>();
    int nAutoGeneratedLinks = 0;
    int nManualLinks = 0;
    foreach (AnalyticalLink alink in alinks)
    {
        if (alink.IsAutoGenerated() == true)
            nAutoGeneratedLinks++;
        else
            nManualLinks++;
    }
    string msg = "Auto-generated AnalyticalLinks: " + nAutoGeneratedLinks;
    msg += "\nManually created AnalyticalLinks: " + nManualLinks;
    TaskDialog.Show("AnalyticalLinks", msg);
}

The static method AnalyticalLink.Create() creates a new analytical link. Rather than connecting the two elements directly, the connection is created between two Hubs. The Hub class represents a connection between two or more Autodesk Revit Elements.

The following example creates a new analytical link between two selected FamilyInstance objects. It uses a filter to find all Hubs in the model and then the GetHub() method searches the hubs to find one which references the Id of the AnalyticalModel of each FamilyInstance.

Code Region: Creating a new AnalyticalLink

public void CreateLink(Document doc, FamilyInstance fi1, FamilyInstance fi2)
{
    FilteredElementCollector hubCollector = new FilteredElementCollector(doc);
    hubCollector.OfClass(typeof(Hub));  //Get all hubs
    ICollection<Element> allHubs = hubCollector.ToElements();
    FilteredElementCollector linktypeCollector = new FilteredElementCollector(doc);
    linktypeCollector.OfClass(typeof(AnalyticalLinkType));
    ElementId firstLinkType = linktypeCollector.ToElementIds().First();  //Get the first analytical link type.  
            
    // Get hub Ids from two selected family instance items
    ElementId startHubId = GetHub(fi1.GetAnalyticalModel().Id, allHubs);
    ElementId endHubId = GetHub(fi2.GetAnalyticalModel().Id, allHubs);  

    Transaction tran = new Transaction(doc, "Create Link");
    tran.Start();
    //Create a link between these two hubs.
    AnalyticalLink createdLink = AnalyticalLink.Create(doc, firstLinkType, startHubId, endHubId);  
    tran.Commit();
}

//Get the first Hub on a given AnalyticalModel element
private ElementId GetHub(ElementId hostId, ICollection<Element> allHubs)
{
    foreach (Element ehub in allHubs)
    {
        Hub hub = ehub as Hub;
        ConnectorManager manager = hub.GetHubConnectorManager();
        ConnectorSet connectors = manager.Connectors;
        foreach (Connector connector in connectors)
        {
            ConnectorSet refConnectors = connector.AllRefs;
            foreach (Connector refConnector in refConnectors)
            {
                if (refConnector.Owner.Id == hostId)
                {
                    return hub.Id;
                }
            }
        }
    }
    return ElementId.InvalidElementId;
}