IfcOpenShell正确设置几何体的坐标
创始人
2024-04-26 01:02:40
0

在之前的文章中,我们使用 IfcOpenShell (IOS) 读取 ifc 几何并将其转换为 brep。 当我们读取 wikilab.ifc文件时,一切似乎都是正确的,但真的如此吗?

当你在项目中使用 BIM 时,坐标始终是正确讨论的主题。 就此而言,我建议你阅读 Dion Moult 的文章 IFC Coordinate Reference Systems and Revit 以及文章中引用的参考资料。

本教程使用的 IfcOpenShell 版本:0.6.0a1,教程中的完整代码可以从这里下载。

1、IFC 中的Placement

几何体通常有自己的局部坐标系 (LCS)。 为什么 ?

以航站楼为例。 你经常在一个项目中使用几种类型的风道末端。 在每个空间中多次复制相同的航站楼几何形状。 如果你的几何图形是使用世界坐标系 (WCS) 定义的,则需要为每个几何体定义一个新几何图形。 如果你的几何图形在其自己的 LCS 中定义,则可以在任何地方使用相同的几何图形,并给出其相对于另一个参考的位置。

在 ifc 规范中,通风终端是 IfcAirTerminal (IFC4) 或 IfcFlowTerminal (IFC2x3)。 两者都继承自IfcProduct(如墙、窗、管道等),它具有 IfcObjectPlacement 类型的 ObjectPlacement 属性。

ObjectPlacement属性描述产品在空间中的放置,放置可以是绝对的(相对于世界坐标系)、相对的(相对于另一个产品的对象放置)或约束(例如相对于网格轴)。 它由 IfcObjectPlacement 的各种子类型决定,其中包括用于确定对象坐标系变换的轴放置信息。 — IFC 文档中的ObjectPlacement属性定义
IfcLocalPlacement 子类型,我认为是最常见的,有 2 个属性:

  • #1 - IfcObjectPlacement 类型的 PlacementRelTo。 如果填充位置是相对的。 如果空放置使用 WCS。
  • #2 - RelativePlacement 基本上是一个 2D 或 3D 坐标。
    可以链接相对位置,例如: AirTerminal << space << buildingstorey << building << Site。 要检索相对于 WCS 的对象放置,需要通过完整链转换第一个相对放置。

2、IfcOpenShell 中的Placement

IfcOpenShell 可用作解析器以获取与 IfcSchema 中定义的完全相同的位置。 然而,它也有方便的工具来避免抓取整个相对放置链。 要了解这一点的选项是 USE_WORLD_COORDS :

/// Specifies whether to apply the local placements of building elements
/// directly to the coordinates of the representation mesh rather than
/// to represent the local placement in the 4x3 matrix, which will in that
/// case be the identity matrix.
USE_WORLD_COORDS = 1 << 1,

当你像我们在之前的文章中所做的那样显示几何体时,坐标是使用几何体的局部坐标系 给出的。 它不可见,因为我们的墙放置在坐标 0,0,0 处。 现在让我们使用来自 ifcopenshell academy 的脚本来生成一个放置在 20,10,3 的新墙。 默认情况下,脚本还会在 0,0,0 处生成一堵墙。 要修改它的相对位置,我们需要修改以下行:

wall_placement = create_ifclocalplacement(ifcfile, relative_to=storey_placement)

考虑到函数定义,我们需要将这一行替换为:

wall_placement = create_ifclocalplacement(ifcfile, point=(20., 10., 3.), relative_to=storey_placement)

现在,如果你尝试根据我们之前的脚本从这个新创建的 hello_wall.ifc 加载几何图形,将看到墙仍然位于 0,0,0,这是错误的。

在这里插入图片描述

为了正确放置它,我们有 2 个选项:使用矩阵变换和 USE_WORLD_COORDINATES 设置。

3、使用Placement矩阵

正如你在创建几何体时在其源代码中所述,它的位置由一个 4×3 矩阵给出。 但要注意,当显示为元组时,IfcOpenShell 矩阵和 FreeCAD 矩阵是转置的:

  • IfcOpenShell 矩阵值是 4 个连续向量的 xyz 的元组。格式 : (v1.x, v1.y, v1.z, v2.x, v2.y …, v4.z)
  • FreeCAD 矩阵构造函数最多占用 16 个浮点数。 按 x、y、z 值分组的 4 个向量。格式 : (v1.x, v2.x, v3.x, v4.x, v1.y, …, v4.z, 0, 0, 0, 1)

关于 FreeCAD 矩阵的最后 0、0、0、1。 正如 OpenGL 教程的矩阵章节中所述:

这很快就会变得更加清楚,但现在,请记住这一点:
如果 W == 1,则向量 (X,Y,Z,1) 是空间中的一个位置。
如果 W == 0,则向量 (X,Y,Z,0) 是一个方向。
(事实上 ,永远记住这一点。) - OpenGL Tutorial Matrices Chapter

所以我们将使用一个函数将 IfcOpenShell 矩阵转置为 FreeCAD 矩阵:

def ios_to_fc_matrix(ios_matrix):m_l = list()for i in range(3):line = list(ios_matrix[i::3])line[-1] *= SCALEm_l.extend(line)return FreeCAD.Matrix(*m_l)

在几何形状创建之后,我们调用它来设置对象的位置:

    # Create FreeCAD shape from Open Cascade BREPfc_shape = Part.Shape()fc_shape.importBrepFromString(occ_shape)# Ifc lenght internal unit : meter. FreeCAD internal unit : mm.fc_shape.scale(SCALE)# Shape scale must be applied before shape placement else placement scale would be doubledfc_shape.Placement = ios_shape_to_fc_placement(ios_shape)

这样我们就得到了正确放置的墙:
在这里插入图片描述

4、USE_WORLD_COORDINATES

定义设置仍然是相同的过程:

settings.set(settings.USE_WORLD_COORDS, True)

我们可以保留相同的代码库,因为它将应用不会改变任何内容的单位矩阵。 通过运行脚本,你将再次获得正确放置的墙,但这次位置仍然是 0, 0, 0,这意味着几何顶点坐标是用它们的绝对坐标定义的:

在这里插入图片描述

出于在第一部分中解释的原因,我倾向于说此解决方案不是 HVAC 领域中 CAD/BIM 工作的最佳选择。 目前 FreeCAD 以这种方式导入和导出 ifc 我将调查原因并可能在论坛上发布此主题。


原文链接:IfcOpenShell坐标问题 — BimAnt

相关内容

热门资讯

贵州镇远涌溪乡:政策赋能连片种... 寒阳铺洒,田垄铺金。在贵州省黔东南州镇远县涌溪乡古楼坪村打鸟坪,300亩连片马铃薯田如碧毯铺展,翻耕...
每周股票复盘:安正时尚(603... 截至2026年1月16日收盘,安正时尚(603839)报收于8.05元,较上周的8.18元下跌1.5...
每周股票复盘:盛邦安全(688... 截至2026年1月16日收盘,盛邦安全(688651)报收于54.89元,较上周的55.07元下跌0...
每周股票复盘:陕建股份(600... 截至2026年1月16日收盘,陕建股份(600248)报收于3.59元,较上周的3.61元下跌0.5...
本市财政建立常态化“政策体检”... 本报讯(记者 孙杰)本市财政建立常态化“政策体检”机制,将推动财政资金持续提质增效。记者获悉,市财政...
每周股票复盘:重庆啤酒(600... 截至2026年1月16日收盘,重庆啤酒(600132)报收于51.9元,较上周的52.39元下跌0....
每周股票复盘:新疆天业(600... 截至2026年1月16日收盘,新疆天业(600075)报收于5.4元,较上周的5.34元上涨1.12...
每周股票复盘:电子城(6006... 截至2026年1月16日收盘,电子城(600658)报收于5.81元,较上周的6.03元下跌3.65...
每周股票复盘:三峡水利(600... 截至2026年1月16日收盘,三峡水利(600116)报收于6.63元,较上周的6.53元上涨1.5...