znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第06章:结构与框架——桁架、支撑与结构框架

在建筑信息模型中,结构体系由承重构件(柱、梁)和抗侧力构件(支撑、剪力墙等)共同组成。Elements 提供了一套层次分明的结构元素类型系统,本章将覆盖以下内容:

  • StructuralFraming:所有线性结构构件的抽象基类
  • Beam:梁——沿任意方向的结构构件
  • Column:柱——竖向承重构件
  • Brace:支撑——对角抗侧力构件
  • Frame:框架——沿多边形周界扫描截面
  • Joist:托梁——带弦杆和腹杆的组合结构
  • IsElementDefinition + CreateInstance 模式在结构工程中的应用
  • 综合示例:创建带支撑的完整钢结构框架

6.1 StructuralFraming:结构框架基类

StructuralFraming 是所有线性结构构件(梁、柱、支撑、托梁)的抽象基类。它继承自 GeometricElement,定义了结构构件共有的几何语义:将截面沿中心线扫掠

public abstract class StructuralFraming : GeometricElement
{
    // 中心线
    public BoundedCurve Curve { get; set; }

    // 截面轮廓(可以是矩形、圆形或标准型钢)
    public Profile Profile { get; set; }

    // 起始端退距(例如:柱端连接板区域不生成实体)
    public double StartSetback { get; set; }

    // 终止端退距
    public double EndSetback { get; set; }

    // 截面绕中心线的旋转角度(度)
    public double Rotation { get; set; }
}

6.1.1 几何生成机制

每个 StructuralFraming 子类的 UpdateRepresentations() 方法通过创建 Sweep(扫掠)操作来生成三维几何:

截面 (Profile) ──┐
                  ├── Sweep ──→ 三维实体
中心线 (Curve)  ──┘
  • 如果 CurveLine(直线):生成单个扫掠体
  • 如果 CurveIndexedPolycurve(多段线):为每段分别生成扫掠体
  • StartSetbackEndSetback 控制两端缩进,避免与相邻构件的几何重叠
  • Rotation 控制截面绕轴旋转(例如:H 型钢翼缘朝向)

6.1.2 材质默认值

StructuralFraming 的默认材质是 BuiltInMaterials.Steel,体现其”结构钢”的语义定位。子类可以显式传入其他材质来覆盖。

6.1.3 体积计算

StructuralFraming 提供了 Volume() 方法,当前仅支持直线中心线的体积计算:

public double Volume()
{
    return this.Profile.Area() * this.Curve.Length();
}

注意:对于曲线(弧线、椭圆弧等),Volume() 会抛出 InvalidOperationException,因为曲线扫掠的体积计算尚未实现。

6.2 Beam:梁

BeamStructuralFraming 最直接的使用者,代表任意方向的结构梁。它不添加任何新属性,完全依赖基类的能力。

6.2.1 创建直线梁

using Elements;
using Elements.Geometry;

// 定义定位线:从 (0,0,0) 到 (6,0,0),即 X 方向 6 米
var line = new Line(
    new Vector3(0, 0, 3),   // 起点,Z=3 表示架设在 3 米高处
    new Vector3(6, 0, 3)    // 终点
);

// 定义矩形截面:宽 0.3m,高 0.5m
var profile = new Profile(Polygon.Rectangle(0.3, 0.5));

// 创建梁
var beam = new Beam(line, profile, material: BuiltInMaterials.Steel);

model.AddElement(beam);

6.2.2 创建曲线梁

Beam 的定位线可以是任意 BoundedCurve,不限于直线:

// 弧形梁:90 度弯梁,半径 5 米
var arc = new Arc(Vector3.Origin, 5.0, 0.0, Math.PI / 2);
var curvedBeam = new Beam(arc, profile, material: BuiltInMaterials.Steel);

// 圆形环梁
var circle = new Circle(4.0);
var ringBeam = new Beam(circle, profile, material: BuiltInMaterials.Steel);

6.2.3 使用退距和旋转

// 两端各退 0.5 米(例如:避开柱连接区)
var beam = new Beam(
    line,
    profile,
    startSetback: 0.5,     // 起始端退 0.5m
    endSetback: 0.5,       // 终止端退 0.5m
    rotation: 15.0,        // 截面绕轴旋转 15 度
    material: BuiltInMaterials.Steel
);

6.2.4 使用标准型钢截面

Elements 内置了多套标准型钢截面库,在使用前推荐安装 Hypar.Elements NuGet 包(2.0+ 版本自带型钢工厂):

using Elements.Geometry.Profiles;

// H 型钢(宽翼缘工字钢)
var wfFactory = new WideFlangeProfileFactory();
var wfProfile = wfFactory.GetProfileByType(WideFlangeProfileType.W10x100);

var beam = new Beam(line, wfProfile, material: BuiltInMaterials.Steel);

// 方钢管
var shsFactory = new SHSProfileFactory();
var shsProfile = shsFactory.GetProfileByType(SHSProfileType.SHS200X200X10);
var boxBeam = new Beam(line, shsProfile, material: BuiltInMaterials.Steel);

Elements 支持的型钢截面工厂包括:

工厂 命名空间 截面类型
WideFlangeProfileFactory Elements.Geometry.Profiles 宽翼缘工字钢(W 型)
HSSPipeProfileFactory Elements.Geometry.Profiles 圆钢管(HSS 圆管)
RHSProfileFactory Elements.Geometry.Profiles 矩形钢管(RHS)
SHSProfileFactory Elements.Geometry.Profiles 方钢管(SHS)
LProfileFactory Elements.Geometry.Profiles 角钢(L 型)

6.3 Column:柱

Column 也继承自 StructuralFraming,但它有自己的定位语义——通过 Location(底部位置)和 Height(柱高)定义,而非通用的 Curve 中心线。构造函数内部自动创建竖向直线。

6.3.1 创建柱子

using Elements;
using Elements.Geometry;

// 柱的基本参数
var location = new Vector3(3, 5, 0);  // 底部位置 (X=3, Y=5, Z=0)
var height = 4.0;                      // 柱高 4 米
var profile = new Profile(Polygon.Rectangle(0.4, 0.4));  // 400x400 方柱

// 创建柱(curve 参数传入 null,由 Column 内部自动生成竖直线)
var column = new Column(location, height, null, profile, material: BuiltInMaterials.Steel);

model.AddElement(column);

6.3.2 柱的几何生成

查看源码中 Column 构造函数的内部实现:

public Column(Vector3 location, double height, Curve curve, Profile profile, ...)
    : base(
        new Line(
            new Vector3(location.X, location.Y, location.Z + height),  // 柱顶
            location                                                    // 柱底
        ),
        profile, ...)

要点:

  • 内部创建的 Line 从 Z=height(柱顶)到 Z=0(柱底),方向向下
  • 不需要手动传入 Curve,传 null 即可(该参数仅为 schema 兼容性保留)
  • LocationHeight 作为独立属性存储,便于后续查询

6.3.3 为柱子添加退距和旋转

var column = new Column(
    new Vector3(0, 0, 0),
    3.5,
    null,
    profile,
    startSetback: 0.1,    // 柱底退 0.1m(柱脚板区域)
    endSetback: 0.1,      // 柱顶退 0.1m(柱头连接区)
    rotation: 0.0,
    material: BuiltInMaterials.Steel
);

6.3.4 柱的 Transform

通过 Transform 可以旋转或平移整根柱子:

var t = new Transform();
t.Rotate(Vector3.ZAxis, 45.0);   // 绕 Z 轴旋转 45 度
t.Move(new Vector3(5, 0, 0));    // 沿 X 平移 5 米

var rotatedColumn = new Column(
    Vector3.Origin, 3.0, null, profile,
    transform: t,
    material: BuiltInMaterials.Steel
);

6.4 Brace:支撑

BraceStructuralFraming 的另一个子类,代表对角支撑或抗侧力斜撑。在语义上它与 Beam 完全相同(都只是将截面沿曲线扫掠),但通过独立的类型名称来表达其结构用途。

6.4.1 创建对角支撑

using Elements;
using Elements.Geometry;

// 从柱底 (0, 0, 0) 到上方梁端 (3, 0, 3) 的对角支撑
var braceLine = new Line(
    new Vector3(0, 0, 0),
    new Vector3(3, 0, 3)
);

var braceProfile = new Profile(Polygon.Rectangle(0.15, 0.15));
var brace = new Brace(braceLine, braceProfile, BuiltInMaterials.Steel);

model.AddElement(brace);

6.4.2 X 形支撑(十字交叉撑)

// 两对角支撑组成 X 形
var height = 3.0;
var width = 4.0;
var origin = new Vector3(0, 0, 0);

// 第一道斜撑:左下 → 右上
var diag1 = new Brace(
    new Line(origin, new Vector3(origin.X + width, 0, origin.Z + height)),
    braceProfile,
    BuiltInMaterials.Steel
);

// 第二道斜撑:左上 → 右下
var diag2 = new Brace(
    new Line(
        new Vector3(origin.X, 0, origin.Z + height),
        new Vector3(origin.X + width, 0, origin.Z)
    ),
    braceProfile,
    BuiltInMaterials.Steel
);

model.AddElements(new[] { diag1, diag2 });

6.4.3 支撑的退距

支撑通常需要从柱/梁的交点处退让一定距离,为节点板留出空间:

var brace = new Brace(
    braceLine,
    braceProfile,
    BuiltInMaterials.Steel,
    startSetback: 0.3,    // 起点退让 0.3m
    endSetback: 0.3       // 终点退让 0.3m
);

6.5 Frame:框架

Frame 是 Elements 中一个较为特殊的结构元素:它不继承自 StructuralFraming,而是直接继承自 GeometricElement。它的概念是:将一个截面沿闭合多边形周界扫掠,形成框架结构。

6.5.1 Frame 的定位方式

Frame ≠ 线构件(Beam/Column/Brace 沿一条线扫掠)
Frame = 框架构件(Profile 沿一个闭合周界扫掠)

这使 Frame 适用于:门窗框、设备框架、幕墙龙骨等场景。

6.5.2 创建 Frame

using Elements;
using Elements.Geometry;

// 定义一个矩形周界(框架外形)
var perimeter = Polygon.Rectangle(2.0, 3.0);

// 定义截面(框架构件的断面)
var frameProfile = new Profile(Polygon.Rectangle(0.1, 0.15));

// 创建框架(offset 参数将周界向内偏移)
var frame = new Frame(
    perimeter,
    frameProfile,
    offset: 0.0,                    // 周界偏移量(0 = 沿原周界扫掠)
    material: BuiltInMaterials.Steel
);

model.AddElement(frame);

6.5.3 带偏移的 Frame

offset 参数使周界向内偏移后扫掠,适合表示”外框比内框大”的场景:

// 周界向内偏移 0.05m 后扫掠(模拟窗框外缘与内缘的差异)
var frame = new Frame(
    Polygon.Rectangle(1.5, 2.0),
    new Profile(Polygon.Rectangle(0.08, 0.12)),
    offset: 0.05,
    material: BuiltInMaterials.Steel
);

6.5.4 非矩形 Frame

Frame 接受任意 Polygon 作为周界:

// 六边形框架
var hexPerimeter = Polygon.Ngon(6, 1.5);
var hexFrame = new Frame(hexPerimeter, frameProfile, material: BuiltInMaterials.Steel);

// L 形框架
var lShape = Polygon.LShape(4, 4, 2, 2);
var lFrame = new Frame(lShape, frameProfile, material: BuiltInMaterials.Steel);

6.5.5 Frame 的几何实现

查看源码,Frame.UpdateRepresentations() 内部实现:

public override void UpdateRepresentations()
{
    this.Representation.SolidOperations.Clear();
    this.Representation.SolidOperations.Add(
        new Sweep(this.Profile, this.Curve, 0.0, 0.0, 0.0, false)
    );
}

本质上就是一个沿多边形周界的 Sweep 操作,与 Beam 的几何生成方式完全一致。

6.5.6 Frame 与 FramePiece 的关系

在实际的 Elements 源码中,不存在独立的 FramePieceNodeFrame 自身就是一个完整的元素——它不拆分为”框架段”和”连接节点”,而是直接将截面沿整个周界一步完成扫掠。若需要更精细地控制每一段框架(例如每段使用不同截面),应将各个边分别创建为 Beam 元素。

6.6 Joist:托梁(桁架梁)

JoistStructuralFraming 下最复杂的子类,代表带上下弦杆和斜腹杆的托梁(也常称为桁架梁或钢格栅梁)。它不依赖简单的 “截面沿曲线扫掠”,而是通过程序化生成多个独立的 Sweep 操作来构建完整的几何体。

6.6.1 Joist 的组成

       上弦杆 (Top Chord) ── L 型钢(双角钢背靠背)
           │\    │\    │\
腹杆 (Web)│  \  │  \  │  \    ← 交替布置的斜杆
           │    \│    \│    \
       下弦杆 (Bottom Chord) ── L 型钢(双角钢背靠背)

关键属性:

属性 类型 说明
TopChordProfile LProfile 上弦杆角钢截面
BottomChordProfile LProfile 下弦杆角钢截面
WebProfile LProfile 腹杆角钢截面
Depth double 托梁高度
CellCount int 腹杆网格数
SeatDepth double 支座深度
DistanceToFirstPanel double 第一块节间距离
JoistPoints List<Vector3> 上弦支撑点列表(用于放置次梁)

6.6.2 创建托梁

using Elements.Geometry.Profiles;

var profileFactory = new LProfileFactory();
var topChordProfile = profileFactory.GetProfileByType(LProfileType.L8X8X5_8);
var bottomChordProfile = profileFactory.GetProfileByType(LProfileType.L8X8X5_8);
var webProfile = profileFactory.GetProfileByType(LProfileType.L2X2X1_8);

var joistLine = new Line(
    new Vector3(0, 0, 0),
    new Vector3(0, 12, 0)   // 跨度 12 米
);

var joist = new Joist(
    joistLine,
    topChordProfile,
    bottomChordProfile,
    webProfile,
    depth: Units.InchesToMeters(48),          // 高度 48 英寸
    cellCount: 20,                             // 20 个腹杆节间
    seatDepth: Units.InchesToMeters(2.5),     // 支座深 2.5 英寸
    distanceToFirstPanel: Units.FeetToMeters(2.0),  // 第一面板距 2 英尺
    material: BuiltInMaterials.Steel
);

model.AddElement(joist);

6.6.3 托梁上的次梁放置

Joist.JoistPoints 记录了上弦各支撑点的世界坐标,可用于自动放置次梁:

// 在托梁上弦的每个支撑点放置一根次梁
var secondaryBeamProfile = new Profile(Polygon.Rectangle(0.15, 0.3));

foreach (var point in joist.JoistPoints)
{
    var secBeamLine = new Line(point, new Vector3(point.X + 3, point.Y, point.Z));
    var secBeam = new Beam(secBeamLine, secondaryBeamProfile, material: BuiltInMaterials.Steel);
    model.AddElement(secBeam);
}

6.7 Truss:桁架

在 Elements 当前版本(2.4.x)的源码中,没有独立的 Truss 类型。然而,Elements 的类型体系提供了多种方式来构建桁架结构:

6.7.1 方案一:用 Beam 组合平面桁架

将桁架的每根杆件(上弦、下弦、腹杆)逐一创建为 Beam

// 创建一个最简单的三角桁架(上弦 + 下弦 + 斜腹杆)
var span = 6.0;
var rise = 1.0;

// 下弦
var bottomChord = new Beam(
    new Line(new Vector3(0, 0, 0), new Vector3(span, 0, 0)),
    chordProfile, material: BuiltInMaterials.Steel
);

// 上弦(分两段)
var topMid = new Vector3(span / 2, 0, rise);
var topLeft = new Beam(
    new Line(Vector3.Origin, topMid),
    chordProfile, material: BuiltInMaterials.Steel
);
var topRight = new Beam(
    new Line(topMid, new Vector3(span, 0, 0)),
    chordProfile, material: BuiltInMaterials.Steel
);

// 腹杆
var leftWeb = new Beam(
    new Line(new Vector3(span / 2, 0, 0), topMid),
    webProfile, material: BuiltInMaterials.Steel
);

model.AddElements(new Element[] { bottomChord, topLeft, topRight, leftWeb });

6.7.2 方案二:用 Joist 创建桁架梁

对于规则的平行弦桁架(例如楼面钢格栅),直接使用 Joist 是最便捷的方式——它自动生成上下弦杆和交替斜腹杆。

6.7.3 方案三:自定义 Truss 类型

遵循 Elements 的 Schema-first 开发模式,可以基于 StructuralFramingGeometricElement 扩展出自定义的 Truss 类型(详见第15章:Schema 驱动开发)。

6.8 IsElementDefinition + CreateInstance 在结构工程中的模式

在结构工程中,大量构件是重复且标准化的——例如同一楼层的数十根柱子使用相同的截面和材质。如果每根柱子都存储完整的几何数据,会产生巨大的冗余。Elements 通过 “元素定义-实例” 模式优雅地解决了这个问题。

6.8.1 模式回顾

// 步骤 1:创建"元素定义"(模板,不直接渲染)
var definition = element with { IsElementDefinition = true };

// 步骤 2:调用 CreateInstance 创建实例
var instance = definition.CreateInstance(transform, name);

(这一模式在第02章 2.1.3 节和 2.7 节已有详细介绍,这里聚焦于结构工程的应用场景。)

6.8.2 场景:标准化柱网

using Elements;
using Elements.Geometry;

var model = new Model();

// 步骤 1:创建"标准柱"定义
var columnDef = new Column(
    Vector3.Origin,
    4.0,
    null,
    new Profile(Polygon.Rectangle(0.4, 0.4)),
    material: BuiltInMaterials.Steel
)
{
    IsElementDefinition = true,
    Name = "标准钢柱 400x400"
};
model.AddElement(columnDef);

// 步骤 2:在柱网各位置创建实例
double gridX = 6.0;   // 柱距 X 方向
double gridY = 8.0;   // 柱距 Y 方向
int baysX = 4;
int baysY = 3;

for (int i = 0; i <= baysX; i++)
{
    for (int j = 0; j <= baysY; j++)
    {
        var instance = columnDef.CreateInstance(
            new Transform(i * gridX, j * gridY, 0),
            $"柱-{i}-{j}"
        );
        model.AddElement(instance);
    }
}

Console.WriteLine($"创建了 {(baysX + 1) * (baysY + 1)} 根柱子," +
                  $"但截面几何数据仅存储了 1 份");

6.8.3 场景:跨楼层复用梁定义

// 定义"标准主梁"
var beamDef = new Beam(
    new Line(Vector3.Origin, new Vector3(gridX, 0, 0)),
    new Profile(Polygon.Rectangle(0.3, 0.6)),
    material: BuiltInMaterials.Steel
)
{
    IsElementDefinition = true,
    Name = "标准主梁 300x600"
};
model.AddElement(beamDef);

// 在每层楼的相同位置创建梁实例
for (int floor = 0; floor < 5; floor++)
{
    double z = floor * 4.0;  // 层高 4m

    for (int j = 0; j <= baysY; j++)
    {
        var instance = beamDef.CreateInstance(
            new Transform(0, j * gridY, z),
            $"主梁-F{floor}-Y{j}"
        );
        model.AddElement(instance);
    }
}

6.8.4 场景:支撑系统定义

X 形支撑常用于高层建筑的核心筒和周边抗侧力框架:

// 定义"X 形支撑单元"(不能直接作为 GeometricElement 定义,因为 X 支撑是两个 Brace 的组合)
// 更实际的做法是分别定义单根支撑,再在每跨重复

var braceDef = new Brace(
    new Line(Vector3.Origin, new Vector3(gridX, 0, 4.0)),  // 对角:左下→右上
    new Profile(Polygon.Rectangle(0.2, 0.2)),
    BuiltInMaterials.Steel
)
{
    IsElementDefinition = true,
    Name = "对角支撑 HSS200x200"
};
model.AddElement(braceDef);

// 在每跨的正反方向创建 X 支撑
for (int i = 0; i < baysX; i++)
{
    double baseX = i * gridX;

    // 左下→右上
    model.AddElement(braceDef.CreateInstance(
        new Transform(baseX, 0, 0),
        $"X撑-{i}-1"
    ));

    // 左上→右下(镜像:翻转起点和终点)
    var mirrorDef = new Brace(
        new Line(
            new Vector3(baseX, 0, 4.0),
            new Vector3(baseX + gridX, 0, 0)
        ),
        new Profile(Polygon.Rectangle(0.2, 0.2)),
        BuiltInMaterials.Steel
    )
    {
        IsElementDefinition = true,
        Name = $"对角支撑-反-{i}"
    };
    model.AddElement(mirrorDef);

    model.AddElement(mirrorDef.CreateInstance(
        new Transform(baseX, 0, 0),
        $"X撑-{i}-2"
    ));
}

6.9 综合示例:创建带支撑的钢结构框架

下面是一个完整的示例,创建一榀单跨单层的钢结构框架,包含:4 根柱子 + 4 根梁 + 2 根对角支撑 + 1 块楼板

using Elements;
using Elements.Geometry;
using Elements.Geometry.Solids;

var model = new Model();

// ========================
// 1. 几何参数
// ========================
double spanX = 6.0;       // 跨度 X(米)
double spanY = 8.0;       // 跨度 Y(米)
double height = 4.0;      // 层高(米)
double floorElevation = 4.0;  // 楼面标高

// 截面定义
var colProfile = new Profile(Polygon.Rectangle(0.4, 0.4));     // 400x400 方柱
var beamProfile = new Profile(Polygon.Rectangle(0.3, 0.5));    // 300x500 主梁
var braceProfile = new Profile(Polygon.Rectangle(0.2, 0.2));   // 200x200 方管支撑

// 柱位(4 个角点)
var columnPositions = new[]
{
    new Vector3(0, 0, 0),
    new Vector3(spanX, 0, 0),
    new Vector3(spanX, spanY, 0),
    new Vector3(0, spanY, 0),
};

// ========================
// 2. 创建柱子
// ========================
foreach (var pos in columnPositions)
{
    var col = new Column(pos, height, null, colProfile, material: BuiltInMaterials.Steel)
    {
        Name = $"柱-{pos.X}-{pos.Y}"
    };
    model.AddElement(col);
}

// ========================
// 3. 创建梁(柱顶之间)
// ========================
// 定义梁的定位线——4 条边
var beamLines = new[]
{
    // X 方向梁(Y=0 和 Y=spanY 处)
    new Line(new Vector3(0, 0, height), new Vector3(spanX, 0, height)),
    new Line(new Vector3(0, spanY, height), new Vector3(spanX, spanY, height)),
    // Y 方向梁(X=0 和 X=spanX 处)
    new Line(new Vector3(0, 0, height), new Vector3(0, spanY, height)),
    new Line(new Vector3(spanX, 0, height), new Vector3(spanX, spanY, height)),
};

for (int i = 0; i < beamLines.Length; i++)
{
    var beam = new Beam(beamLines[i], beamProfile, material: BuiltInMaterials.Steel)
    {
        Name = $"主梁-{i + 1}"
    };
    model.AddElement(beam);
}

// ========================
// 4. 创建对角支撑(X 形)
// ========================
// 在 XZ 平面(Y=0)的一跨创建 X 支撑
var xBrace1 = new Brace(
    new Line(
        new Vector3(0, 0, 0),           // 左下:柱底
        new Vector3(spanX, 0, height)    // 右上:柱顶
    ),
    braceProfile,
    BuiltInMaterials.Steel,
    startSetback: 0.2,
    endSetback: 0.2
)
{ Name = "支撑-A" };
model.AddElement(xBrace1);

var xBrace2 = new Brace(
    new Line(
        new Vector3(0, 0, height),       // 左上:柱顶
        new Vector3(spanX, 0, 0)         // 右下:柱底
    ),
    braceProfile,
    BuiltInMaterials.Steel,
    startSetback: 0.2,
    endSetback: 0.2
)
{ Name = "支撑-B" };
model.AddElement(xBrace2);

// 在 YZ 平面(X=spanX)的另一侧创建支撑
var yBrace1 = new Brace(
    new Line(
        new Vector3(spanX, 0, 0),
        new Vector3(spanX, spanY, height)
    ),
    braceProfile,
    BuiltInMaterials.Steel,
    startSetback: 0.2,
    endSetback: 0.2
)
{ Name = "支撑-C" };
model.AddElement(yBrace1);

var yBrace2 = new Brace(
    new Line(
        new Vector3(spanX, 0, height),
        new Vector3(spanX, spanY, 0)
    ),
    braceProfile,
    BuiltInMaterials.Steel,
    startSetback: 0.2,
    endSetback: 0.2
)
{ Name = "支撑-D" };
model.AddElement(yBrace2);

// ========================
// 5. 创建楼板
// ========================
var floorPerimeter = Polygon.Rectangle(spanX, spanY);
var floorProfile = new Profile(floorPerimeter);

var floor = new Floor(
    floorProfile,
    0.2,                                    // 板厚 0.2m
    new Transform(0, 0, floorElevation),    // 标高处 Z=4.0
    material: BuiltInMaterials.Concrete
)
{ Name = "二层楼板" };
model.AddElement(floor);

// ========================
// 6. 导出模型
// ========================
model.ToGlTF("steel_frame.glb");
Console.WriteLine($"模型共包含 {model.Elements.Count} 个元素");

6.9.1 运行结果

运行上述代码后,会在当前目录生成 steel_frame.glb 文件,可以用任何 glTF 查看器打开。你将看到:

  • 4 根方钢柱支撑起一个矩形框架
  • 4 根主梁连接柱顶
  • 两组 X 形对角支撑提供抗侧刚度
  • 一块混凝土楼板覆盖在框架顶部

6.9.2 扩展:多层多跨框架

将上述示例扩展为多层多跨,只需嵌套循环:

int stories = 3;     // 层数
int baysX = 2;       // X 方向跨数
int baysY = 2;       // Y 方向跨数

for (int s = 0; s < stories; s++)
{
    double baseZ = s * height;

    for (int i = 0; i <= baysX; i++)
    {
        for (int j = 0; j <= baysY; j++)
        {
            var pos = new Vector3(i * spanX, j * spanY, baseZ);

            // 柱(仅当 j=0 且 i=0 时底部从地面开始)
            var col = new Column(pos, height, null, colProfile,
                material: BuiltInMaterials.Steel)
            { Name = $"柱-{s}-{i}-{j}" };
            model.AddElement(col);

            // X 方向梁
            if (i < baysX)
            {
                var beamX = new Beam(
                    new Line(pos, new Vector3((i + 1) * spanX, j * spanY, baseZ + height)),
                    beamProfile, material: BuiltInMaterials.Steel
                )
                { Name = $"梁X-{s}-{i}-{j}" };
                model.AddElement(beamX);
            }

            // Y 方向梁
            if (j < baysY)
            {
                var beamY = new Beam(
                    new Line(pos, new Vector3(i * spanX, (j + 1) * spanY, baseZ + height)),
                    beamProfile, material: BuiltInMaterials.Steel
                )
                { Name = $"梁Y-{s}-{i}-{j}" };
                model.AddElement(beamY);
            }
        }
    }
}

6.10 结构元素类型对照总表

类型 基类 定位方式 几何操作 典型用途
StructuralFraming GeometricElement 抽象基类 Sweep
Beam StructuralFraming Curve(中心线) Sweep 主梁、次梁、连梁
Column StructuralFraming Location + Height 内部生成竖直线 + Sweep 钢柱、混凝土柱
Brace StructuralFraming Curve(中心线) Sweep 对角支撑、斜撑
Joist StructuralFraming Curve(中心线) 多 Sweep 组合 钢格栅托梁、桁架梁
Frame GeometricElement Polygon(周界) Sweep 沿周界 门窗框、设备框架
Floor GeometricElement Profile + Transform Extrude 楼板

6.11 小结

本章全面介绍了 Elements 中的结构元素体系:

  • StructuralFraming 是线性结构构件的抽象基类,提供 Curve + Profile + Sweep 的通用几何生成机制
  • Beam 代表任意方向的梁,支持直线、曲线和多段线中心线
  • Column 通过 Location + Height 定义,内部自动处理为竖直线
  • Brace 专门用于对角支撑,带有退距控制避免节点碰撞
  • Frame 将截面沿闭合多边形周界扫掠,适用于框架类构件
  • Joist 是程序化生成的托梁/桁架梁,包含完整的上下弦杆和腹杆
  • Truss 类型在当前版本中不存在,但可通过组合 Beam 或使用 Joist 来实现
  • IsElementDefinition + CreateInstance 模式在结构工程中极具价值,可大幅减少大型模型的数据冗余
  • 综合示例展示了完整的钢结构框架建模:柱 + 梁 + 支撑 + 楼板

下一章将介绍空间、开洞与地形元素。


← 上一章 目录 下一章 →