Building a continuous rigid frame bridge is not particularly difficult; the process is primarily driven by code. Many talented developers use Dynamo to achieve this, and I believe it’s quite effective. I have also utilized Dynamo for this purpose, although I find using dedicated plugins more enjoyable.
The core concept is straightforward: place the family in the correct position, retrieve the family parameters, and then modify those parameters accordingly.
You can watch the final result in this video: __AI_S_TURL_0__
using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
namespace BuildBridgeQuick
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class Class1 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document revitDoc = commandData.Application.ActiveUIDocument.Document; // Access the document
Application revitApp = commandData.Application.Application; // Access the application
UIDocument uiDoc = commandData.Application.ActiveUIDocument; // Access the active UI document
// Select a single box girder instance with variable cross-section
Selection sel = uiDoc.Selection;
Reference ref1 = sel.PickObject(ObjectType.Element, "Select a variable cross-section box girder instance");
Element elem = revitDoc.GetElement(ref1);
FamilyInstance familyInstance = elem as FamilyInstance;
if (familyInstance == null)
{
TaskDialog.Show("Error 1", "Box girder instance not selected. Please try again!");
return Result.Failed;
}
// Extract the family type name and display it
FamilySymbol symbol = familyInstance.Symbol;
TempName.FamInsName = symbol.Name;
// Open the parameter input form
Form1 form1 = new Form1();
form1.ShowDialog();
List list = new List { elem.Id };
ICollection elementIds = list;
// Retrieve parameters of the variable cross-section box girder
Parameter param1 = familyInstance.LookupParameter("iH"); // Height of section i
Parameter param2 = familyInstance.LookupParameter("iHI5"); // Height of i-section bottom plate
Parameter param3 = familyInstance.LookupParameter("iT"); // Width of i-section web plate
Parameter param4 = familyInstance.LookupParameter("iHI1"); // Height of i-section top plate
Parameter param5 = familyInstance.LookupParameter("jH"); // Height of section j
Parameter param6 = familyInstance.LookupParameter("jHI5"); // Height of j-section bottom plate
Parameter param7 = familyInstance.LookupParameter("jT"); // Width of j-section web plate
Parameter param8 = familyInstance.LookupParameter("jHI1"); // Height of j-section top plate
Parameter param9 = familyInstance.LookupParameter("BeamLength"); // Segment length
Parameter param10 = familyInstance.LookupParameter("detZ"); // Height difference between two sections (Z axis)
Parameter param11 = familyInstance.LookupParameter("detY"); // Height difference between two sections (Y axis)
int j = 0;
for (int i = 0; i < ListData.List_SJGC.Count - 1; i++)
{
j = i + 1;
// Update family parameters according to the data in ListData
using (Transaction transaction1 = new Transaction(revitDoc, "Change Family Parameters"))
{
transaction1.Start();
param1.Set(ListData.List_XLG[i] / 304.8);
param2.Set(ListData.List_DBH[i] / 304.8);
param3.Set(ListData.List_FBH[i] / 304.8);
param4.Set(ListData.List_TBH[i] / 304.8);
param5.Set(ListData.List_XLG[j] / 304.8);
param6.Set(ListData.List_DBH[j] / 304.8);
param7.Set(ListData.List_FBH[j] / 304.8);
param8.Set(ListData.List_TBH[j] / 304.8);
param9.Set(ListData.List_JDCD[j] / 304.8);
param10.Set(ListData.List_SJGC[i] / 304.8 - ListData.List_SJGC[j] / 304.8);
param11.Set(ListData.List_Y[i] / 304.8 - ListData.List_Y[j] / 304.8);
transaction1.Commit();
}
// Place the updated family instance at the corresponding position
using (Transaction transaction2 = new Transaction(revitDoc, "Copy the family to the corresponding location"))
{
transaction2.Start();
XYZ targetPoint = new XYZ(ListData.List_X[i] / 304.8, ListData.List_Y[i] / 304.8, ListData.List_SJGC[i] / 304.8);
LocationPoint familyInstancePoint = familyInstance.Location as LocationPoint;
XYZ translation = new XYZ(
ListData.List_X[i] / 304.8 - familyInstancePoint.Point.X,
ListData.List_Y[i] / 304.8 - familyInstancePoint.Point.Y,
ListData.List_SJGC[i] / 304.8 - familyInstancePoint.Point.Z);
ElementTransformUtils.CopyElements(revitDoc, elementIds, translation);
transaction2.Commit();
}
}
// Clear data stored in ListData
ListData.List_DBH.Clear();
ListData.List_FBH.Clear();
ListData.List_JDCD.Clear();
ListData.List_SJGC.Clear();
ListData.List_TBH.Clear();
ListData.List_X.Clear();
ListData.List_XLG.Clear();
ListData.List_Y.Clear();
return Result.Succeeded;
}
}
}
xuebim
Follow the latest BIM developments in the architecture industry, explore innovative building technologies, and discover cutting-edge industry insights.
← Scan with WeChat













Must log in before commenting!
Sign Up