Revit API access to Structural Connection parameters

I was just wondering if anyone knows if the “special” parameters in structural connections are possible to set/get with the Revit API? Or does possibly the Structural connection addin have its own API accessible in one way or the other? I couldn’t find any with my sparse API knowledge.

As pr now they are generally useless, since you have to set the parameters manually for each connection unless you copy them out in the model.

3 Likes

Looks like they are stored in Autodesk.Revit.DB.ExtensibleStorage, and they can be accessed like shown in this sample from the SDK called GenericStructuralConnection:

    /// <summary>
    /// Match properties for detailed structural connections.
    /// </summary>
    /// <param name="activeDoc">The active document.</param>
    /// <param name="message">Set message on failure.</param>
    /// <returns>Returns the status of the operation.</returns>
    public static Result MatchPropertiesDetailedStructuralConnection(UIDocument activeDoc, ref string message)
    {
        Result ret = Result.Succeeded;

        // Prompt to select a structural connection
        StructuralConnectionHandler srcConn = StructuralConnectionSelectionUtils.SelectConnection(activeDoc);
        StructuralConnectionHandler destConn = StructuralConnectionSelectionUtils.SelectConnection(activeDoc);

        if (srcConn != null && destConn != null)
        {
            using (Transaction tran = new Transaction(activeDoc.Document, "Match properties"))
            {
                tran.Start();

                // Do the properties match.
                Schema masterSchema = GetSchema(activeDoc.Document, srcConn);
                Entity masterEnt = srcConn.GetEntity(masterSchema);

                // You could also access and modify the connection parameters.
                IList<Field> fields = masterSchema.ListFields();
                foreach (Field field in fields)
                {
                    if (field.ValueType == typeof(string))
                    {
                        IList<string> parameters = masterEnt.Get<IList<string>>(field);
                        foreach (string str in parameters)
                        {
                            // Do something.
                        }
                    }
                }

                destConn.SetEntity(masterEnt);

                TransactionStatus ts = tran.Commit();
                if (ts != TransactionStatus.Committed)
                {
                    message = "Failed to commit the current transaction !";
                    ret = Result.Failed;
                }
            }
        }
        else
        {
            message = "There must be two connections selected !";
            ret = Result.Failed;
        }


        return ret;
    }

You need this as well:

    /// <summary>
    /// Get the Extensible storage schema
    /// </summary>
    private static Schema GetSchema(Document doc, StructuralConnectionHandler connection)
    {
        Schema schema = null;

        Guid guid = GetConnectionHandlerTypeGuid(connection, doc);
        if (guid != null && guid != Guid.Empty)
            schema = Schema.ListSchemas().Where(x => x.GUID == guid).FirstOrDefault();

        return schema;
    }

    /// <summary>
    /// Get the unique identifier of the structural steel connection type
    /// </summary>
    /// <param name="conn">structural connection</param>
    /// <param name="doc">current document</param>
    /// <returns>returns the unique identifier of the input connection type</returns>
    private static Guid GetConnectionHandlerTypeGuid(StructuralConnectionHandler conn, Document doc)
    {
        if (conn == null || doc == null)
            return Guid.Empty;

        ElementId typeId = conn.GetTypeId();
        if (typeId == ElementId.InvalidElementId)
            return Guid.Empty;

        StructuralConnectionHandlerType connType = (StructuralConnectionHandlerType)doc.GetElement(typeId);
        if (connType == null || connType.ConnectionGuid == null)
            return Guid.Empty;

        return connType.ConnectionGuid;
    }
2 Likes

Einar what are this two sets of code? Ready script for node? Could you give a pro tip for dummies how to use them in dynamo? I’m ready to sell my wife, children and kidney to get it :stuck_out_tongue:

Jostein is 100% right - steel connections in Revit are useless witthout API access :confused:

The code is taken from a Revit Add-in sample which can be compiled and run as a commamd from the ribbon. It is possible to rewrite it to python, and it can be simplified a lot.

@Michael_Gawel @jostein_olsen

I created a simplified python version to copy settings from one connection to several others of the same type:

Python script:

# Code by Einar Raknes, 2018

import clr

# Import List ( ICollection(ElementId) = List[ElementId]() )
clr.AddReference('System')
from System.Collections.Generic import List

# Import Revit API
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
from Autodesk.Revit.DB.ExtensibleStorage import *

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

# Import ToDSType(bool) extension method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

# Input
srcConn = UnwrapElement(IN[0])
if isinstance (IN[1], list):
	destConnList = UnwrapElement(IN[1])
else:
	desConnList = [UnwrapElement(IN[1])]
	
type = doc.GetElement(srcConn.GetTypeId())
connectionGuid = type.ConnectionGuid
schema = Schema.Lookup(connectionGuid)
entity = srcConn.GetEntity(schema)

 #Make changes to Revit DB in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
OUT = [destConn.SetEntity(entity) for destConn in destConnList]
TransactionManager.Instance.TransactionTaskDone()
4 Likes

Hi there, In my c# project StructuralConnectionSelectionUtils function isn’t recognized. Should be due to the references. I saw in the python code that you’ve imported ‘RevitNodes’ and ‘RevitServices’ referances.

I couldn’t find those references. Where are those references stored so I can include them in my project? Can you please help? Thank you!

Also dynamo code has the following error. What could be the reason? :frowning:

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 43, in
Exception: The input argument “schema” of function Autodesk::Revit::Proxy::DB::ElementProxy::GetEntity or one item in the collection is null at line 1287 of file d:\ship\2019_px64\source\revit\revitdbapi\gensrc\APIElementProxy.cpp.
Parameter name: schema

This means that what you have selected as Source Connection and plugged in to port IN[0], does not have a valid guid.

Well not sure.

I select the connection element in Revit and I can retrieve the guid, but the problem is Schema.Lookup function returns null. I’ve tried it on other connection types as well. They all return null.

I have the same problem. I tried both dynamo and Revit API with visual studio addin but no luck.
Every time, program throws error like yours. Did you find any solution?

No unfortunately not. It seems they have removed this in 2019 version of Revit.

Seems like the setttings are stored somewhere else than in extensible storage in Revit 2019!

I tried to snoop around with Revit lookup, but can’t figure out if they are still accessible.

One workaround is to wrap the detailed/parameteric connection in a custom one and update in “Edit Custom Connection Type” mode. When you hit finish all the connections of that type is updated.

I’m not completely sure that addresses the same problem, but the Revit SDK samples do in fact include a small sample that shows how to read and update detailed parameters for a steel connection in Revit; you can find it here:

/Samples/SampleCommandsSteelElements/CS/UpdateConnectionDetailedParameters.cs.

1 Like

Are the Connection Parameters(schema lookup) really broken in 2019? Or is there just another way to do this that the dev’s forgot to mention.

I need to get at the parameters for a coped connection and none of the sample codes work at this point.

1 Like

Hi, does anyone know how to get Structural Connection parameters to be edited in Dynamo right now?

Hey Natalia,

I am trying to find a way to do this, and am trying out the ModifyConnectionParametersService. Which is one of the BuiltInExternalServices.

my pseudocode looks like this:

serviceId = ExternalServices.BuiltInExternalServices.ModifyConnectionParametersService
service = ExternalServiceRegistry.GetService(serviceId)
serverIds = service.GetRegisteredServerIds()

serverId = serverIds[0]
server = service.GetServer(serverId)

then with the server I can do:

server.ModifyConnectionParameters(ModifyConnectionParametersServiceData)

but here is the problem: I can not find a way to create this Data that I need as an argument, because it has no constructor.

Any idea if this direction would work?

Thanks!

Lucas