前言
这个例子的目标是去创建一些钢结构的构件,需要用户安装 Autodesk 公司的另外一款钢结构设计软件 AdvanceSteel。这篇博客只从代码的角度来大致看一下它的逻辑。
内容
Advance Steel
Advance Steel 的官网链接:https://www.autodesk.com/products/advance-steel/features
在结构连接中添加新的构件
Revit 2021 SDK\Samples\SampleCommandsSteelElements\CS\AddElementsToConnection.cs
核心逻辑:
// 选择一个联接 StructuralConnectionHandler
StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc);
// 选择要被联接的构件
IList<ElementId> ids = Utilities.Functions.SelectConnectionElements(activeDoc, "Select elements to add to connection :");
// 把这些构件加到联接中
trans.Start();
conn.AddElementIds(ids);
ts = trans.Commit();
Revit 2021 SDK\Samples\SampleCommandsSteelElements\CS\AddElementsToCustomConnection.cs
核心逻辑:
// 选择一个联接 StructuralConnectionHandler,IsCustom 必须是 true
StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc);
if (!(conn.IsCustom()))
{
return Result.Failed;
}
// 选择要被联接的构件,这里的逻辑和上面的有些区别,选择的构件类别不同
IList<Reference> refs = Utilities.Functions.SelectConnectionElementsCustom(activeDoc);
// 把这些构件加到联接中
trans.Start();
StructuralConnectionHandlerType.AddElementsToCustomConnection(conn, refs);
ts = trans.Commit();
背景计算
Revit 2021 SDK\Samples\SampleCommandsSteelElements\CS\BackgroundCalculation.cs
这个命令里面出现了 AdvanceSteel 直接相关的类型,Plate
:
// https://help.autodesk.com/view/ADSTPR/2019/ENU/?guid=GUID-19A366F0-C51F-45AB-AF0C-46E59ABFD284
// 详见 AdvanceSteel API 介绍
private void CreateHolesInPlate()
{
// Create a plate and add holes to it
Point3d plateOrig = Point3d.kOrigin;
Plane platePlane = new Plane(plateOrig, Vector3d.kZAxis);
Plate plate = new Plate(500, 500, platePlane, plateOrig);
plate.WriteToDb();
ConnectionHolePlate connectionHole = new ConnectionHolePlate(plate, new Matrix3d());
plate.AddFeature(connectionHole);
// Create a rectangular arranger for the holes in a 3x2 pattern
BoundedRectArranger arranger = new BoundedRectArranger(300, 200);
arranger.Nx = 3;
arranger.Ny = 2;
connectionHole.Arranger = arranger;
// Define the holes for the set
connectionHole.Hole = new SlottedHole(20.0, 52.0, SlottedHole.eDirection.kXAxis);
}
在和 Revit API 混合编写的时候,创建 Plate
的代码:
// 暂时没有找到 FabricationTransaction,猜测来自于 Advance Steel 的 API
using (FabricationTransaction trans = new FabricationTransaction(_doc, false, "Create structural plate"))
{
// Create a plate using Advance Steel API (internal Advance Steel units are in mm)
Point3d orig = new Point3d(Utilities.Functions.FEET_TO_MM * plateCenter.X,
Utilities.Functions.FEET_TO_MM * plateCenter.Y,
Utilities.Functions.FEET_TO_MM * plateCenter.Z);
Plate plate = new Plate(new Autodesk.AdvanceSteel.Geometry.Plane(Point3d.kOrigin, Vector3d.kZAxis), orig, 2000, 1000);
plate.Thickness = 10;
// Write plate to database.
plate.WriteToDb();
plateUniqueId = plate.GetUniqueId();
trans.Commit();
}
从上面的例子里面,由一个地方需要引起注意,AdvanceSteel 应该是通过 plate.WriteToDb()
这个形式来确认数据生成。
另外,还涉及到了一些 BackgroundCalculation,在这个例子里面是由于调用了 MovePlate
导致的。至于有多少种情况会导致 Revit 进入 BackgroundCalculation 状态不确定,但这个例子应该是会发生。
_plateId = CreatePlate(XYZ.Zero);
// This would generate background calculation (You can see the task running in the Revit "Background processes" window).
MovePlate();
bool backgroundCalc = _doc.IsBackgroundCalculationInProgress(); // It should be true.
可以通过注册一个 idle 事件在 Revit 空闲的时候去处理需要的逻辑。
// Register for the idling event and wait for the background calculations to finish.
uiApp.Idling += IdlingHandler;
Anchor Pattern
d:\revit 2021 sdk\samples\SampleCommandsSteelElements\CS\CreateAnchorPattern.cs
核心逻辑也是直接用了 Advance Steel 的 API,由此可知 FabricationTransaction 是为钢结构准备的:
// Selecting the elements to create the anchor pattern on
Reference eRef = activeDoc.Selection.PickObject(ObjectType.Element, "Pick an element to create the anchor pattern on");
// Start detailed steel modeling transaction
using (FabricationTransaction trans = new FabricationTransaction(activeDoc.Document, false, "Create anchor pattern"))
{
// We create the anchor pattern using Advance Steel classes and objects only.
// for more details, please consult http://www.autodesk.com/adv-steel-api-walkthroughs-2019-enu
List<FilerObject> filerObjectList= new List<FilerObject>();
FilerObject filerObj = Utilities.Functions.GetFilerObject(doc, eRef);
if (null == filerObj)
{
return Result.Failed;
}
filerObjectList.Add(filerObj);
// Point of reference for the anchor pattern. We use GlobalPoint to create the pattern on the plate. GlobalPoint is the point where the plate is being hit when selected.
Point3d p1 = new Point3d(eRef.GlobalPoint.X, eRef.GlobalPoint.Y, eRef.GlobalPoint.Z);
Point3d p2 = new Point3d(p1.x + 0.5, p1.y + 0.5, p1.z + 0.5);
AnchorPattern anchorPattern = new AnchorPattern(p1 * Utilities.Functions.FEET_TO_MM, p2 * Utilities.Functions.FEET_TO_MM, new Vector3d(1, 0, 0), new Vector3d(0, 1, 0));
anchorPattern.Connect(filerObjectList.ToArray(), Autodesk.AdvanceSteel.ConstructionTypes.AtomicElement.eAssemblyLocation.kOnSite);
anchorPattern.WriteToDb();
trans.Commit();
}
其他例子
其他创建 AdvanceSteel 构件的例子也是非常的简单易懂,可自行查阅。
CreateBoltPattern.cs
CreateContourCut.cs
CreateCopeSkewed.cs
CreateCornerCut.cs
CreatePlate.cs
CreatePlateHole.cs
CreateShearStudPattern.cs
CreateShortening.cs
CreateWeldPoint.cs
DeleteConnection.cs
RemoveElementsFromConnection.cs
RemoveSubelementsFromCustomConnection.cs