znlgis 博客

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

第05章:建筑元素——墙、梁、柱、楼板

在建筑信息模型中,墙(Wall)、梁(Beam)、柱(Column)、楼板(Floor)是最基本的四种建筑元素。它们共同构成建筑的承重体系和空间围合。Elements 为每种元素提供了专用的类型和一套一致的几何生成模式——所有元素都通过覆写 UpdateRepresentations() 方法,在其中声明性地描述自己的三维形状(Extrude / Sweep / Lamina 等 SolidOperation),再由内核统一计算实体。

本章将逐一深入这四种核心建筑元素及相关的 Panel(面板)类型,并在最后给出一个包含全部元素的综合示例。

5.1 Wall:墙

墙是建筑中最常见的空间分隔与围护元素。在 Elements 中,墙的类型层次如下:

GeometricElement
  └── Wall(抽象基类)
        ├── StandardWall    —— 以中心线 + 厚度 + 高度定义
        └── WallByProfile   —— 以立面轮廓 + 厚度 + 中心线定义

5.1.1 StandardWall:标准墙

StandardWall 是最常用的墙类型。它只需要三个参数:中心线CenterLine)、厚度Thickness)和高度Height)。内部通过一个 Extrude 操作沿中心线方向拉伸矩形截面生成墙体。

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

// 中心线:从 (0,0,0) 到 (5,0,0),长 5 米
var centerLine = new Line(
    new Vector3(0, 0, 0),
    new Vector3(5, 0, 0)
);

// 创建标准墙:厚度 0.2m,高度 3.0m
var wall = new StandardWall(
    centerLine,
    0.2,        // 厚度
    3.0         // 高度
)
{
    Name = "外墙-A1",
    Material = BuiltInMaterials.Concrete
};

StandardWallUpdateRepresentations() 内部逻辑:

  1. 以中心线为基准,向两侧各偏移 Thickness / 2 形成墙的平面轮廓
  2. Height 为拉伸长度,沿 +Z 方向执行 Extrude
  3. 处理开洞(Openings)——每个开洞对应一个 IsVoid = trueExtrude,在 CSG 布尔运算中从墙体中减去

5.1.2 为墙添加开洞

StandardWall 提供两种添加开洞(门窗洞口)的方式:矩形洞口(按宽高指定)和自定义多边形洞口。

var wall = new StandardWall(
    new Line(new Vector3(0, 0, 0), new Vector3(8, 0, 0)),
    0.2,    // 厚度
    3.0     // 高度
);

// 方式一:矩形洞口(宽 1.2m,高 2.1m,距墙起点 2m,距地面 0m)
wall.AddOpening(1.2, 2.1, 2.0, 0.0);

// 方式二:矩形窗口(宽 1.5m,高 1.2m,距墙起点 5m,距地面 1.2m)
wall.AddOpening(1.5, 1.2, 5.0, 1.2);

// 方式三:自定义多边形洞口
var archOpening = new Polygon(new[]
{
    new Vector3(0, 0),
    new Vector3(1.0, 0),
    new Vector3(1.0, 1.5),
    new Vector3(0.5, 2.0),
    new Vector3(0, 1.5),
});
wall.AddOpening(archOpening, 3.5, 0);

参数说明:

  • x:洞口沿墙中心线方向的定位距离(从墙起点算起)
  • y:洞口底面距墙底的高度
  • depthFront / depthBack:洞口在墙体内外两侧的深度(默认为 1,即完全贯穿)

5.1.3 WallByProfile:按轮廓生成墙

WallByProfile 适用于具有非矩形立面轮廓的墙——例如带山墙的端墙、弧形顶墙、阶梯形墙等。你需要提供一个 Polygon 描述墙的立面形状(Perimeter),然后指定一个中心线和厚度。

// 定义立面轮廓:底部宽 6 米,高 3 米,顶部带三角形山墙
var perimeter = new Polygon(new[]
{
    new Vector3(0, 0),       // 左下角
    new Vector3(6, 0),       // 右下角
    new Vector3(6, 3),       // 右侧直墙顶
    new Vector3(3, 4.5),     // 山墙顶点
    new Vector3(0, 3),       // 左侧直墙顶
});

// 中心线(墙的平面定位)
var centerline = new Line(
    new Vector3(0, 0, 0),
    new Vector3(0, 6, 0)
);

// 创建按轮廓定义的墙:厚度 0.2m
var gableWall = new WallByProfile(
    perimeter,
    0.2,            // 厚度
    centerline
)
{
    Name = "山墙",
    Material = BuiltInMaterials.Concrete
};

WallByProfile 提供了几个便捷方法:

// 获取墙的计算高度
double height = gableWall.GetHeight();  // 返回 4.5

// 获取墙的计算剖面(包含开洞后的 Profile)
Profile computedProfile = gableWall.GetProfile();

// 为 WallByProfile 添加开洞(深度参数)
gableWall.AddOpening(archOpening, depthFront: 1.0, depthBack: 1.0);

5.1.4 墙的几何内部机制

无论 StandardWall 还是 WallByProfile,其 UpdateRepresentations() 的核心逻辑都是:

1. 根据参数计算墙的平面轮廓 Polygon
2. 创建 Extrude 操作(沿 +Z 方向拉伸 Height)
3. 对每个 Opening 创建 IsVoid=true 的 Extrude
4. 将以上操作填入 Representation.SolidOperations

这使得墙的处理与 Elements 的 CSG 内核无缝衔接——墙体和洞口都是同样的 SolidOperation 描述,内核在 UpdateBoundsAndComputeSolid() 阶段统一计算布尔差集。

5.2 Beam:梁

梁是水平(或倾斜)的结构承重元素。在 Elements 中,梁继承自 StructuralFraming(结构框架)基类:

GeometricElement
  └── StructuralFraming(抽象基类)
        ├── Beam      —— 梁
        ├── Column    —— 柱
        ├── Brace     —— 支撑
        └── Joist     —— 托梁(桁架式轻型梁)

5.2.1 Beam 的基本用法

Beam 的核心参数是中心线曲线BoundedCurve)和截面轮廓Profile)。中心线可以是直线、弧线或其他有界曲线:

using Elements;
using Elements.Geometry;
using Elements.Geometry.Profiles;

var model = new Model();

// --- 直梁 ---
var straightBeam = new Beam(
    new Line(new Vector3(0, 0, 3), new Vector3(6, 0, 3)),
    new Profile(Polygon.Rectangle(0.3, 0.5))  // 宽 0.3m,高 0.5m
)
{
    Name = "主梁-B1",
    Material = BuiltInMaterials.Steel
};

// --- 弧形梁 ---
var arcBeam = new Beam(
    new Arc(
        new Transform(new Vector3(8, 3, 3), Vector3.XAxis, Vector3.YAxis),
        3.0,                        // 半径
        Math.PI * 0.25,             // 起始角 45°
        Math.PI * 0.75              // 终止角 135°
    ),
    new Profile(Polygon.Rectangle(0.3, 0.5)),
    transform: new Transform(0, 0, 0),
    material: BuiltInMaterials.Steel
)
{
    Name = "弧形梁-B2"
};

5.2.2 Beam 的高级参数

Beam 构造函数支持退距(Setback)和截面旋转:

var beam = new Beam(
    curve: new Line(new Vector3(0, 0, 3), new Vector3(8, 0, 3)),
    profile: new Profile(Polygon.Rectangle(0.3, 0.6)),
    startSetback: 0.15,     // 起点退距(梁端缩进 0.15m)
    endSetback: 0.15,       // 终点退距
    rotation: 0,            // 截面绕轴线旋转角度(度)
    material: BuiltInMaterials.Steel
);

Beam.Volume() 方法可以计算梁的体积(对非直线梁会抛出异常,当前仅支持直线梁的体积计算):

double volume = straightBeam.Volume();
Console.WriteLine($"直梁体积: {volume:F3} m3");

5.2.3 Beam 与 Wall 的关键区别

特性 Wall Beam
几何操作 Extrude(沿平面轮廓 +Z 拉伸) Sweep(沿曲线扫掠截面)
定位方式 中心线(平面方向) + 高度 中心线曲线(3D 方向)
截面定义 矩形(由 Thickness + Height 隐含)或自定义 Profile 明确的 Profile(可以是型钢截面)
适用场景 建筑墙体(空间分隔) 结构梁(承重)
开洞支持 有(Openings 集合)
曲线路径 仅直线 支持直线、弧线、椭圆弧等任意 BoundedCurve

5.2.4 使用型钢截面(Wide Flange / HSS)

Elements 提供了 Elements.Geometry.Profiles 命名空间下的标准型钢截面工厂:

using Elements.Geometry.Profiles;

// 使用宽翼缘型钢截面(如 W10x100)
var wideFlangeFactory = new WideFlangeProfileFactory();
var wProfile = wideFlangeFactory.GetProfileByType(WideFlangeProfileType.W10x100);

var steelBeam = new Beam(
    new Line(new Vector3(0, 0, 4), new Vector3(10, 0, 4)),
    wProfile,
    material: BuiltInMaterials.Steel
)
{
    Name = "型钢梁-W10x100"
};

// 使用 HSS 空心结构型钢截面
var hssFactory = new HSSPipeProfileFactory();
var hssProfile = hssFactory.GetProfileByType(HSSPipeProfileType.HSS10_000x0_625);

var hssColumn = new Column(
    new Vector3(5, 5, 0),
    4.0,
    null,
    hssProfile,
    material: BuiltInMaterials.Steel
)
{
    Name = "HSS柱"
};

5.2.5 Joist:桁架式托梁

Joist 是一种特殊的轻型梁,用于楼面或屋面支撑系统。与普通梁不同,托梁是由上弦杆、下弦杆和腹杆构成的桁架结构:

using Elements.Geometry.Profiles;

// 创建上弦、下弦和腹杆的角钢截面
var topChord = new LProfile("topChord", 0.076, 0.076, 0.006);     // 3"x3"x1/4"
var bottomChord = new LProfile("bottomChord", 0.051, 0.051, 0.006); // 2"x2"x1/4"
var web = new LProfile("web", 0.038, 0.038, 0.006);               // 1.5"x1.5"x1/4"

var joist = new Joist(
    new Line(new Vector3(0, 0, 4), new Vector3(8, 0, 4)),  // 中心线
    topChord,
    bottomChord,
    web,
    depth: 0.6,              // 桁架高度
    cellCount: 12,           // 桁架单元格数
    seatDepth: 0.1,          // 支座深度
    distanceToFirstPanel: 0, // 到第一个节点的距离
    material: BuiltInMaterials.Steel
)
{
    Name = "楼面托梁-J1"
};

5.3 Column:柱

Column 是竖直的结构承重元素,同样继承自 StructuralFraming。它用位置点 + 高度定义,而非中心线曲线。

5.3.1 Column 基本用法

// 在指定位置创建一根柱子
var column = new Column(
    new Vector3(2, 3, 0),       // 柱底位置(Location)
    4.0,                         // 高度
    null,                        // 中心线曲线(竖柱时传 null)
    new Profile(Polygon.Rectangle(0.4, 0.4))  // 截面轮廓
)
{
    Name = "柱-C1",
    Material = BuiltInMaterials.Concrete
};

Column 的两个关键属性:

  • Location:柱底面中心点的三维坐标(Vector3
  • Height:柱的竖直高度
  • Profile:截面轮廓(从 StructuralFraming 继承)

5.3.2 批量创建柱网

在实际项目中,柱通常按规则网格布置:

var model = new Model();
var columnProfile = new Profile(Polygon.Rectangle(0.3, 0.3));

// 定义柱网参数
double gridX = 6.0;    // X 方向间距
double gridY = 8.0;    // Y 方向间距
int colsX = 4;
int colsY = 3;
double height = 3.6;

for (int i = 0; i < colsX; i++)
{
    for (int j = 0; j < colsY; j++)
    {
        var location = new Vector3(i * gridX, j * gridY, 0);
        var col = new Column(location, height, null, columnProfile)
        {
            Name = $"柱-{i + 1}{j + 1}",
            Material = BuiltInMaterials.Concrete
        };
        model.AddElement(col);
    }
}

Console.WriteLine($"共创建 {colsX * colsY} 根柱");

5.3.3 Column 的退距与旋转

与 Beam 一样,Column 也支持退距和截面旋转:

var column = new Column(
    new Vector3(0, 0, 0),
    3.6,
    null,
    columnProfile,
    startSetback: 0.0,    // 柱底退距
    endSetback: 0.0,      // 柱顶退距
    rotation: 45          // 截面旋转 45°
);

5.3.4 Column 与 Beam 的对比

特性 Column Beam
定位方式 点位置(Location)+ 竖直高度(Height 中心线曲线(BoundedCurve
几何方向 固定沿 +Z 方向 沿曲线的切向量方向
中心线曲线参数 存在但通常为 null(仅用于 Schema 兼容) 必需参数
典型截面 方形、圆形、H 型钢 I 型钢、H 型钢、矩形
所属类别 结构框架(StructuralFraming) 结构框架(StructuralFraming)

5.4 Floor:楼板

Floor 是水平的建筑元素,由平面轮廓多边形(Perimeter)和厚度(Thickness)定义。与 Wall 类似,Floor 通过 Extrude 操作沿 -Z 方向(向下)拉伸轮廓生成实体。

5.4.1 Floor 基本用法

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

// 方式一:矩形楼板
var rectFloor = new Floor(
    new Profile(Polygon.Rectangle(10, 8)),
    0.2,    // 厚度 0.2m
    transform: new Transform(0, 0, 0),  // 放在 Z=0 平面
    material: BuiltInMaterials.Concrete
)
{
    Name = "一楼楼板"
};

// 方式二:自定义多边形楼板
var customPolygon = new Polygon(new[]
{
    new Vector3(0, 0),
    new Vector3(12, 0),
    new Vector3(12, 5),
    new Vector3(8, 5),
    new Vector3(8, 9),
    new Vector3(0, 9),
});
var customFloor = new Floor(
    new Profile(customPolygon),
    0.25,
    transform: new Transform(0, 0, 3.6),  // 放在 Z=3.6m(二楼)
    material: BuiltInMaterials.Concrete
)
{
    Name = "二楼楼板"
};

5.4.2 楼板开洞

使用 AddOpening 方法为楼板添加洞口(楼梯间、管道井等):

var floor = new Floor(
    new Profile(Polygon.Rectangle(10, 8)),
    0.2
);

// 矩形洞口:1.5m × 2.0m,位于楼板的 (3, 2) 处
floor.AddOpening(1.5, 2.0, 3.0, 2.0);

// 自定义多边形洞口:圆形楼梯间
var circleOpening = new Circle(Vector3.Origin, 0.8).ToPolygon(32);
floor.AddOpening(circleOpening, 7.0, 4.0);

楼板的 Volume()Area() 方法可计算已扣除洞口后的体积和面积:

double area = floor.Area();      // 扣除洞口后的净面积
double volume = floor.Volume();  // 扣除洞口后的净体积
Console.WriteLine($"楼板面积: {area:F2} m2");
Console.WriteLine($"楼板体积: {volume:F3} m3");

5.4.3 L 形与复杂形状楼板

Elements 提供了方便的工厂方法创建 L 形和复杂多边形:

// L 形楼板(Polygon.LShape 工厂方法)
var lShapePolygon = Polygon.LShape(
    8.0,    // 总长(X 方向)
    6.0,    // 总宽(Y 方向)
    3.0,    // L 形短边长度
    4.0     // L 形短边宽度
);
var lShapedFloor = new Floor(
    new Profile(lShapePolygon),
    0.2,
    material: BuiltInMaterials.Concrete
)
{
    Name = "L 形楼板"
};

// N 边形正多边形楼板
var hexagonFloor = new Floor(
    new Profile(Polygon.Ngon(6, 5.0)),  // 六边形,外接圆半径 5m
    0.2
)
{
    Name = "六边形楼板"
};

5.4.4 设置楼板标高

Floor 的标高通过 Transform 参数中的 Z 坐标设置(Elements 2.0+ 不再有独立的 elevation 参数):

// 地下室底板(标高 -3.0m)
var basementFloor = new Floor(
    new Profile(Polygon.Rectangle(15, 10)),
    0.3,
    transform: new Transform(0, 0, -3.0)  // Z = -3.0
)
{
    Name = "地下室底板"
};

// 获取楼板的当前标高
double elevation = basementFloor.Elevation;  // 只读属性,返回 -3.0

5.4.5 Floor 的几何内部机制

Floor.UpdateRepresentations() 的工作流程与 StandardWall 类似:

  1. Profile(含 Perimeter 和 Voids)为基础
  2. 创建 Extrude 操作沿 -Z 方向拉伸 Thickness
  3. 对每个 Opening 创建 IsVoid = trueExtrude
  4. CSG 内核计算布尔差集

5.5 Panel:面板

Panel 是一种零厚度的平面元素,常用于幕墙玻璃面板、装饰板、隔断等场景。与 Floor 不同,Panel 是纯粹的二维面片,不参与体积计算。

5.5.1 Panel 基本用法

// 简单的矩形玻璃面板
var panel = new Panel(
    new Polygon(new[]
    {
        new Vector3(0, 0, 1),
        new Vector3(2, 0, 1),
        new Vector3(2, 0, 3),
        new Vector3(0, 0, 3),
    }),
    BuiltInMaterials.Glass
)
{
    Name = "幕墙玻璃面板"
};

5.5.2 创建幕墙面板阵列

幕墙通常由大量重复的面板组成:

var model = new Model();

double panelWidth = 1.2;
double panelHeight = 3.0;
int panelCount = 8;
double wallLength = panelCount * panelWidth;

for (int i = 0; i < panelCount; i++)
{
    double x = i * panelWidth;
    var perimeter = new Polygon(new[]
    {
        new Vector3(x, 0, 0),
        new Vector3(x + panelWidth, 0, 0),
        new Vector3(x + panelWidth, 0, panelHeight),
        new Vector3(x, 0, panelHeight),
    });

    var curtainPanel = new Panel(perimeter, BuiltInMaterials.Glass)
    {
        Name = $"幕墙面板-{i + 1}"
    };
    model.AddElement(curtainPanel);
}

5.5.3 Panel 的属性和方法

var panel = new Panel(somePolygon);

// 计算面板面积
double area = panel.Area();

// 计算面板的法向量(基于前三个顶点)
Vector3 normal = panel.Normal();
Console.WriteLine($"面板法向量: ({normal.X:F2}, {normal.Y:F2}, {normal.Z:F2})");

5.5.4 Panel 的几何机制

UpdateRepresentations() 中,Panel 使用 Lamina 操作(而非 ExtrudeSweep):

Lamina:直接用 2D 轮廓面片表示,无厚度

这使 Panel 非常轻量,适合大量实例化而不会显著增加模型复杂度。

5.6 综合示例:创建一个完整的房间模型

下面是一个完整的综合示例,创建一个包含四面墙(带门洞和窗洞)、四根角柱、两根主梁、一块楼板的房间模型,并导出为 glTF。

using System;
using System.IO;
using Elements;
using Elements.Geometry;
using Elements.Geometry.Solids;

public class RoomGenerator
{
    public static Model CreateRoom()
    {
        var model = new Model();

        // ========================
        // 1. 房间参数
        // ========================
        double roomWidth = 6.0;   // 房间宽度(X 方向)
        double roomDepth = 8.0;   // 房间进深(Y 方向)
        double wallHeight = 3.0;  // 墙高
        double wallThickness = 0.2; // 墙厚
        double colSize = 0.35;    // 柱截面边长
        double beamHeight = 0.5;  // 梁高
        double beamWidth = 0.25;  // 梁宽
        double floorThickness = 0.2; // 楼板厚度

        // ========================
        // 2. 创建楼板
        // ========================
        var floorProfile = new Profile(
            Polygon.Rectangle(roomWidth, roomDepth)
        );
        var floor = new Floor(
            floorProfile,
            floorThickness,
            transform: new Transform(0, 0, 0),
            material: BuiltInMaterials.Concrete
        )
        {
            Name = "首层楼板"
        };
        model.AddElement(floor);

        // ========================
        // 3. 创建四面外墙
        // ========================
        // 辅助:在指定坐标创建 StandardWall
        StandardWall CreateWall(double x1, double y1, double x2, double y2, string name)
        {
            return new StandardWall(
                new Line(new Vector3(x1, y1, 0), new Vector3(x2, y2, 0)),
                wallThickness,
                wallHeight,
                material: BuiltInMaterials.Concrete
            )
            { Name = name };
        }

        // 南墙(Y=0,沿 X 方向)
        var southWall = CreateWall(0, 0, roomWidth, 0, "南墙");
        // 在东侧 2.5m 处开一个门洞(宽 1.0m,高 2.1m)
        southWall.AddOpening(1.0, 2.1, 2.5, 0);
        model.AddElement(southWall);

        // 北墙(Y=roomDepth,沿 X 方向)
        var northWall = CreateWall(0, roomDepth, roomWidth, roomDepth, "北墙");
        // 开两个窗洞
        northWall.AddOpening(1.2, 1.2, 1.5, 1.2);  // 左窗
        northWall.AddOpening(1.2, 1.2, 4.0, 1.2);  // 右窗
        model.AddElement(northWall);

        // 西墙(X=0,沿 Y 方向)
        var westWall = CreateWall(0, 0, 0, roomDepth, "西墙");
        model.AddElement(westWall);

        // 东墙(X=roomWidth,沿 Y 方向)
        var eastWall = CreateWall(roomWidth, 0, roomWidth, roomDepth, "东墙");
        // 在中间开一个窗洞
        eastWall.AddOpening(1.5, 1.5, 3.25, 1.0);
        model.AddElement(eastWall);

        // ========================
        // 4. 创建四根角柱
        // ========================
        var columnProfile = new Profile(
            Polygon.Rectangle(colSize, colSize)
        );

        // 柱的位置(四个角点,内缩半个墙厚使柱心对齐墙角)
        double inset = wallThickness / 2;
        var columnPositions = new (double X, double Y, string Name)[]
        {
            (inset, inset, "柱-SW"),                                    // 西南角
            (roomWidth - inset, inset, "柱-SE"),                        // 东南角
            (roomWidth - inset, roomDepth - inset, "柱-NE"),            // 东北角
            (inset, roomDepth - inset, "柱-NW"),                        // 西北角
        };

        foreach (var (x, y, name) in columnPositions)
        {
            var column = new Column(
                new Vector3(x, y, floorThickness),  // 柱底放在楼板上表面
                wallHeight,                          // 柱高与墙齐平
                null,
                columnProfile
            )
            {
                Name = name,
                Material = BuiltInMaterials.Concrete
            };
            model.AddElement(column);
        }

        // ========================
        // 5. 创建两根主梁(架在柱顶)
        // ========================
        double beamElevation = floorThickness + wallHeight; // 梁底标高 = 楼板顶 + 墙高
        var beamProfile = new Profile(
            Polygon.Rectangle(beamWidth, beamHeight)
        );

        // 梁 1:沿 Y 方向,从西南柱到西北柱
        var beam1 = new Beam(
            new Line(
                new Vector3(inset, inset, beamElevation),
                new Vector3(inset, roomDepth - inset, beamElevation)
            ),
            beamProfile,
            material: BuiltInMaterials.Steel
        )
        {
            Name = "主梁-西侧"
        };
        model.AddElement(beam1);

        // 梁 2:沿 Y 方向,从东南柱到东北柱
        var beam2 = new Beam(
            new Line(
                new Vector3(roomWidth - inset, inset, beamElevation),
                new Vector3(roomWidth - inset, roomDepth - inset, beamElevation)
            ),
            beamProfile,
            material: BuiltInMaterials.Steel
        )
        {
            Name = "主梁-东侧"
        };
        model.AddElement(beam2);

        // ========================
        // 6. 导出模型
        // ========================
        return model;
    }

    public static void Main()
    {
        var model = CreateRoom();

        // 统计元素数量
        int wallCount = model.AllElementsOfType<Wall>().Count;
        int beamCount = model.AllElementsOfType<Beam>().Count;
        int columnCount = model.AllElementsOfType<Column>().Count;
        int floorCount = model.AllElementsOfType<Floor>().Count;

        Console.WriteLine("=== 房间模型统计 ===");
        Console.WriteLine($"墙体: {wallCount} 个");
        Console.WriteLine($"梁:   {beamCount} 根");
        Console.WriteLine($"柱:   {columnCount} 根");
        Console.WriteLine($"楼板: {floorCount} 块");
        Console.WriteLine($"总元素数: {model.Elements.Count}");

        // 导出为 glTF(可在浏览器中查看)
        string outputDir = "output";
        Directory.CreateDirectory(outputDir);
        model.ToGlTF(Path.Combine(outputDir, "room.glb"));
        Console.WriteLine($"\n模型已导出到 {outputDir}/room.glb");
    }
}

运行此程序,会在 output/ 目录下生成 room.glb 文件。用任意 glTF 查看器(Windows 3D 查看器、在线 gltf-viewer 或 Three.js 项目)打开,即可看到一个带门洞、窗洞、柱和梁的完整房间模型。

5.7 小结

本章详细介绍了 Elements 中五种建筑元素的创建和使用:

  • StandardWall:以中心线 + 厚度 + 高度定义的标准墙,支持矩形和自定义多边形开洞(门窗)。内部通过 Extrude 沿 +Z 拉伸生成墙体,开洞以 IsVoid = trueExtrude 从墙体中减去。
  • WallByProfile:适用于非矩形立面(如带山墙的墙),以立面多边形 Perimeter + 厚度 + 中心线定义。
  • Beam:结构框架元素,以中心线曲线 + 截面轮廓定义。支持直线、弧线等多种路径,内部用 Sweep 沿曲线扫掠截面生成实体。其兄弟类 Joist 提供更复杂的桁架式托梁结构。
  • Column:竖直结构元素,以底部位置点 + 高度 + 截面轮廓定义。与 Beam 同属 StructuralFraming,但定位方式迥异——柱用点 + 高度,梁用曲线路径。
  • Floor:水平楼板,以平面轮廓 + 厚度定义。支持开洞(楼梯间、管道井)、标高设置和面积/体积计算。Polygon.LShape()Polygon.Ngon() 等工厂方法可快速创建复杂形状。
  • Panel:零厚度平面元素,使用 Lamina 操作,适合幕墙面板和装饰板等轻量级场景。

所有建筑元素共享相同的几何生成模式:构造函数设置参数 → UpdateRepresentations() 创建 SolidOperation → CSG 内核计算实体。掌握这五种元素,就能构建出绝大多数的建筑结构模型。


← 上一章 目录 下一章 →