BIM Revit教程(十一)如何使用机器学习实现 MEP 布局自动化?
# 简介
选择了一个 "点击 "的标题来吸引眼球(营销策略)。更严肃地说,这个项目是在 Revit 模型中实现 MEP(机械、电气、管道)实施附件自动化的首次尝试。
有些项目,尤其是住房项目,利润最低,但同样耗时。事实上,尽管这些单位彼此非常相似,但建模人员必须逐一设计和实施每件设备,并将它们正确地放置在模型上。
我想在这里提出的需求是 2021 年所有建模软件的共同需求,尤其是 Revit:没有任何形式的智能来帮助建模者。无论建模者一开始是想为一个房间还是浴室建模,他都必须从头开始。
要把房间设计成卧室,至少需要摆放一张床、3-4 个插座、一个开关、一个灯具和一个取暖器,然后为每个插座选择合适的旋转方式、合适的高度和合适的连接方式......我的意思是,要正确设计房间,有一条循环往复的路径。无论住房项目如何,所有房间的形状、面积和布局都是相似的。从长远来看,我们的想法是获得一个代理,它能预测建模者的需求,并根据植入的元素提出一个连贯的方案,按照房间的标签放置其他设备。每件设备的高度、旋转、水平、功率和区域等技术信息都将直接整合在一起。这一推理可适用于其他房间标签,如走廊、入口、起居室、厨房等。
这样的进程并非乌托邦。在没有任何信息的情况下,从一个空的住宅平面图中,该程序可以识别出每一个房间,然后根据每一个房间的标签,如上文所述,对其进行不适当的填充。
事实上,这些作品以纯粹的统计方法来思考和处理 BIM。通过有监督的机器学习方法,算法显示出令人信服的结果。
我喜欢这项研究,因为研究人员发现,房间的原始几何形状与它们在住宅中的作用密切相关。通过巧妙地利用多边形的平方等变量,他们发现房间的几何形状本身就说明了问题。如下图所示,在 60% 的情况下,厨房是最小的房间(不包括卫生间)。相反,房间面积越大,就越肯定是客厅。
通过添加新的解释变量,如四等分或等级制,问题就会自行解决。甚至可以应用 "简单 "的决策树来解决这个问题。因此,本研究以数据科学家的方法提出了一个真正的解决方案,其中所使用的解释变量的质量至关重要。
在本文中,我将介绍我利用机器学习 (ML) 实现 MEP 附件自动布局的工作。我的工作分为 5 个部分:
- Revit 模型中的空间数据收集(C#、Revit API)
- 深度 Q-Learning 代理的训练(Python、Keras、Tensorflow、MCTS)
- 对训练好的代理的讨论和反馈
- 基于 Revit 模型中的 ML 预测的 Revit 族实现(C#、Keras.NET、Revit API)
- C# 设置项目和 Python 设置环境
## Revit 模型中的空间数据收集 [1/5]
要使用自动设备布局工具,首先必须为机器提供有用的数据。我目前的项目是在 Revit 上为住房项目的卧室安装电源插座。为此,我需要获取每个 Revit 房间的几何图形。通过 Revit API,我可以查询数字模型,获取所需的信息。数字模型(Revit)在一个文件中包含了所有可以想象到的建筑数据。对于像医院这样的大型项目来说,包含所有这些数据的文件大得惊人。这些模型中包含的数据量无法给出一个数量级。我们可以说这是一个真正的数据库,必须根据需要进行更新、充实和查询。我们必须意识到这一点,这也是使用计算机处理数据的原因。因此,Revit API 可以为每间卧室收集每条形状线的(直角坐标)。我们需要通过存储每个顶点的坐标(x、y、z)来收集红色形状。
我留下了一个代码,它可以让我收集每间卧室和每张床的形状。我仔细地对代码进行了注释。每个人都可以按照自己的意愿来编排代码,这里最主要的是关注数据恢复的动态。首先,收集每个顶点的坐标非常简单。这是在 c_CloneRoom.cs 类中,更具体地说是在 GetRoomShapesFromGroundFace(room) 函数中。
在上述函数中,我 "简单 "地浏览了一组定义给定房间建筑面积的线条。我创建了 C# 对象,以便于管理和操作收集到的数据。这样,每个房间的边界就被恢复了:这是很好的一步!只是,对这些形状的利用并不成功。事实上,这些多边形并没有显示任何关于部件方向的信息。因此,有必要对模型进行查询,以恢复每个房间内的所有设备。
第二步,我在数字模型中提取床铺的轮廓。请注意,这里有一个微妙之处。恢复设备的轮廓比恢复房间的轮廓要精细得多。首先,MEP 配件是 Revit API 中的家庭实例对象。然而,这些对象并不包含任何用于检索轮廓的明确属性。事实上,从编程的角度来看,不可能浏览每个房间,也不可能浏览其中包含的对象。因此,有必要浏览整个数字模型数据库,过滤 "床 "对象,然后根据它们的位置坐标来确定哪个是主房间。
这需要一些疯狂的过程,但只要代码严谨、结构化,就可以做到!GetAllBeds() 函数(c_Start.cs 类)将代码串联起来以实现这一目标。在这个函数中,我举了一个典型的例子,即收集床的形状,并将每个形状分配给其所在的房间。对于门、窗等,可以用同样的方法重复这一过程。有些设备会有一些特殊的复杂问题,但时间长了也能解决。Revit应用程序接口(API)在这方面很不稳定。
我还想强调一下 c_Bed.cs 类中的 GetHostRoom(FamilyInstance fi) 函数的重要性。该函数将一个 Family Instance 对象作为参数,并在该对象的 Room 属性不可用的情况下(这种情况经常发生),根据其 XYZ 位置确定主机房间。这个函数并不完美,但在大多数情况下都能找到房间。该函数克服了 API 中的属性问题。我使用了不同的技巧,代码中会有解释(请参阅函数)。
使用边界框可能是有意义的,但由于种种原因,边界框不够可靠和准确,我就不多说了。
应用所有这些,我们就得到了示例中房间和床铺的所有空间数据。下面是添加门窗后生成的结果。
所有这些信息都是图形化的,机器最终无法使用。一组代表不同实体的二维点对计算机来说意义不大。这就是为什么我使用光栅化技术......以获得具有真实数字矩阵的图像。这些数字矩阵很容易以 .txt 文件的形式存储在一个目录中。然后,这个目录将作为一个真正的数据库,用于强化学习(RL)代理的多样化训练。
为了将所有二维点(笛卡尔数据)转换成图像(整数矩阵),我使用了光栅化(二维)和布雷森汉姆技术。光栅化是将矢量图像转换成光栅图像以便在屏幕上显示的过程。下面是我用来实现这一目标的一个有价值的 GitHub。
我就不多说了,因为互联网上的所有资料都已经很充分、很清楚。让我们来看看我的项目所取得的成果吧。
这些图像将用于向强化学习(RL)代理提供信息,以应用卷积原理。(所有这些将在文章的下一部分详细介绍)。这里还有一个重要细节没有提及。它涉及从 Revit 坐标系((x; y) ∈ |R²)到栅格坐标系((x; y) ∈ |N²,其中 x ∈ [0; 49] 和 y ∈ [0;49])的转换。没有必要深入研究这个问题,但我们应该知道,矩阵位置(0; 0)并不对应于 Revit 中每个矩阵的相同位置。因此,对于每个矩阵,从 Revit 到光栅化矩阵的位置转换都是唯一的。此外,还必须加上 Revit 中 15 厘米或 0.5 英尺的分辨率。
## 深度 Q 学习代理的培训 [2/5]
我使用的技术是强化学习(Reinforcement Learning),更具体地说是深度 Q 学习(Deep Q-Learning)。关于深度 Q-Learning 技术的工作原理,我就不多说了,因为互联网上的所有资料都已足够清晰。我的工作基于谷歌对 AlphaGo 所做的研究,特别是大卫-福斯特(David Forster)开展的一个项目,该项目使用了 AlphaGo 的技术,但将其应用于 "Connect 4 "游戏。
这项工作对我来说非常有价值,因为他出色地成功普及和解释了代理人运作的不同阶段。他的文章非常完整,并可重定向到许多相关资源。非常感谢大卫-福斯特!我想通过极客 Skowster 频道的一系列视频来补充这些资料,这些视频让我更好地了解了深度 Q-Learning 技术的功能。
## 关于训练有素的代理的讨论和反馈 [3/5]
关于深度 Q 学习的这一部分即将结束。所有代码都可以在 David Forster 的 GitHub 上找到,在此再次向他表示感谢。使用深度 Q-Learning 的主要原因是我缺乏数据。RL 提供了以最少的数据训练代理的机会。我们的想法是通过错误学习使其收敛。这种学习过程可以逐步消除不良场景,从而逐渐向良好行为靠拢。
在 BIM 领域,没有大规模的数据库,在我所从事的领域更是如此。到目前为止,集成到模型中的数据都没有经过处理:既没有结构化,也没有标准化。因此,必须对其进行收集、清理甚至格式化。所有这些都需要大量的上游工作,甚至在解决最初问题的实质之前。要在 BIM 中应用机器学习,数据架构师需要完成一项真正的工作。必须设计和组织数据库。数据基础设施对于促进数据访问也至关重要。
我的项目还有很多需要改进的地方。我说的是 50x50 输入矩阵的尺寸。这个尺寸还是太大了,可以通过将矩形腔体旋转 90° 轻松缩小。我们的目标是使主要尺寸(长度)和另一个尺寸(宽度)保持一致。我必须研究这样一种情况,即我把房间里的所有家具(尤其是床)都搬走。那么代理的行为会是怎样的呢?为了进行培训,我在电脑上安装了英伟达™(NVIDIA®)GeForce RTX 2060 SUPER 显卡,但我希望拥有更强的计算能力,以便进一步开展培训和 MCTS 研究。这就是为什么我想尽快使用 Google Colab 的原因。
要使 RL 代理汇聚,还需要添加其他元素。事实上,目前我并没有给他提供门的开启方向,这一点相当具有决定性。在开门的一侧放置一个插座似乎更符合逻辑。这意味着我的 S-score 功能将获得额外奖励。
我们还可以讨论插座的数量,它可以根据房间的面积而变化。如果多边形由 3 个或 5 个插座组成,这将影响面积比(如上所述)。总之,我收集的数据越完整,质量越高,代理就越容易趋向于一致的方案。然而,这些信息必须直接从 Revit 中提取,这并非易事。
## 基于 Revit 模型中的 ML 预测的 Revit 族实现 [4/5]
在最后一节中,我将讨论 Revit 模型中设备布局的 RL 模型实现。我们任务的难点在于如何在 C# 项目中成功提取经过训练的 RL 模型的预测结果。事实上,我们之前已经详细介绍了深度 Q-Learning 代理的创建,所有工作都是在 Python 中完成的。因此,这里的数据互操作性工作至关重要,因为处理 Revit 的语言是 C#。
此外,我们还不能忘记代理预测的一个重要细节。事实上,代理返回的位置 x 和 y 与 50x50 矩阵的索引相对应。因此,这些位置对于我们的 Revit 模型来说并不重要。因此,我们必须将这些矩阵位置转换为 Revit 坐标系。(每个光栅化矩阵中的位置(0,0)与 Revit 坐标系中的位置并不一致,因为并非所有部件都位于模型中的相同位置)。这将在第 1/5 部分的最后进行解释。
因此,我们将看到如何通过 Keras.NET 库使用 C# 来利用机器学习模型。整个 C# 设置项目将在下文最后部分详细介绍。在本部分中,我将介绍如何安装 Keras 库并将其链接到 C# 项目,以及如何定义 Python 环境(第 5/5 部分)。第一步是获取 RL 代理。为此,可以通过 .h5 文件保存机器学习模型。文件生成后,必须将其合并到 C# 项目中。就我而言,该文件包含在我电脑上的一个目录中。理想情况下,该 .h5 文件应链接到项目的资源,以便在本地执行,但目前,当我在本地合并 model.h5 文件时,会产生异常。
下面是根据给定的 XYZ 位置在最近的墙上(垂直投影)植入插座的代码。
## C# 设置项目 [5/5]
首先,您需要通过 NuGet 软件包将 Keras.NET 库下载到您的 C# 项目中。
> MicrosoftCSharp.4.5.0
> pythonnet_netstandard_py38_win.2.5.1
> Numpy.Bare3.8.1.25
> Keras.NET.3.8.5
在 Visual Studio 中:为 .NET Framework 设置 "本地复制 "属性为 False:
> Keras.dll
> MicrosoftCSharp.dll
> Numpy.Bare
> Python.Runtime 之后,尝试执行以下行 :
如果您无法执行上述命令行,这里有一些有用的建议:
> 为了完成这篇有用的文章,如果你仍然有问题,这里有我为解决这个问题所做的一些操作:
> 安装 Python 3.8.6(.exe):这里 确保将 Python 安装到以下目录:C:\Users\mathieu.josserand\AppData\Local\Programs\Python\Python38
> 要管理 "没有名为 numpy 的模块 "的问题:确保 "numpy "如图所示存在 ...
... 如果没有,打开 cmd 并以管理员身份运行,然后在 python 环境中 pip install numpy
> 确保所有这些文件都存在于 C# 项目的 "bin "文件夹中:- Keras.dll - Numpy.Bare.dll - Python.Runtime.dll - Python.Runtime.xml - python38.dll
> 我还在以下目录中添加了上述文件:C:\ProgramData\Autodesk\Revit\Addins\2019
# 写在最后 #
粉丝Free提需求!!如果你正在寻找提效的工具,希望这个免费的功能商店能帮到你
如果你对插件开发感兴趣,欢迎与我们交流一起探讨更多Revit使用技巧
更多AI、MCP功能等你呦~
欢迎评论区留言交流
Free功能百宝box不断更新中,欢迎粉丝提需求跟建议~
❤-------❤若有收获,就点个关注吧 ❤-------❤