我正在开发一个操作IFC(工业基础类(对象的小型Java API。为此,我正在使用外部工具,例如BIMserver。
现在,我正在尝试获取作为IfcProduct实例的每个对象的坐标。但是,我只是通过IfcLocalPlacement
获取另一个IfcProduct的相对坐标,而不是对象的绝对坐标。因此,每个对象的引用是包含它的实体。
我的目标是计算IFC对象之间的距离(只是为了向用户显示信息,我不是在尝试渲染对象等(。例如,IfcSpace
和IfcDistributionControlElement
之间的距离。
有谁知道如何获取每个IFC对象的绝对坐标(而不是相对坐标(?如果您知道一些可以帮助我的 API 或库,您也可以发送它们。
应用/堆叠树中的所有不同IfcLocalPlacement
,直到到达IfcProject
容器。您还可以在 IFC2X3 的文档和 IFC4 的文档中找到解释(据我所知,IfcLocalPlacement
的规格没有改变(:
如果使用相对位置,则以下约定应作为默认相对位置适用。这些约定适用于IfcProduct的所有五个直接子类型,IfcSpatialStructureElement,IfcElement,IfcAnnotation,IfcGrid,IfcPort。更详细的放置信息在上述五种类型的子类型级别给出。
- 对于
IfcSpatialStructureElement
的子类型,以下约定适用
IfcSite
应绝对放置在由IfcProject
的几何表示上下文建立的世界坐标系内IfcBuilding
应相对于IfcSite
的本地放置进行放置IfcBuildingStorey
应相对于IfcBuilding
的本地放置进行放置- 对于
IfcGrid
和IfcAnnotation
适用公约,应将其相对放置
- 到其容器的本地放置(
IfcSite
,IfcBuilding
,IfcBuildingStorey
(
- 它应该是
IfcRelContainedInSpatialStructure
包含关系引用的同一容器元素,- 对于公约适用的
IfcPort
,应将其相对放置
- 到它所属元素的本地位置 (
IfcElement
(
- 它应该是
IfcRelConnectsPortToElement
连接关系引用的同一元素,- 对于公约适用的
IfcElement
,应将其置于相对:
- 到其容器的本地放置(
IfcSite
,IfcBuilding
,IfcBuildingStorey
(
- 它应该是
IfcRelContainedInSpatialStructure
包含关系引用的同一容器元素,- 到通过元素组合关系与之绑定的
IfcElement
的本地放置
- 对于相对于主构件(例如开口(定位的特征,如
IfcRelVoidsElement
和IfcRelProjectsElement
表示,- 对于填充开口的元素(例如门或窗(,如
IfcRelFillsElement
表示,- 对于覆盖元素的覆盖物,如
IfcRelCoversBldgElements
,- 对于聚合到主组件的子组件,如
IfcRelAggregates
和IfcRelNests
所示(
下面是一个函数,可以让你得到任何类的绝对坐标扩展 IfcProduct
public double[] getAbsolutePosition(IfcObjectPlacement ifcObjectPlacement) throws Exception {
if (ifcObjectPlacement instanceof IfcGridPlacement) {
throw new Exception("IfcGridPlacement has not been implemented");
} else if (ifcObjectPlacement instanceof IfcLocalPlacement) {
IfcLocalPlacement ifcLocalPlacement = (IfcLocalPlacement) ifcObjectPlacement;
IfcAxis2Placement relativePlacement = ifcLocalPlacement.getRelativePlacement();
if (relativePlacement instanceof IfcAxis2Placement2D) {
throw new Exception("IfcAxis2Placement2D has not been implemented");
} else if (relativePlacement instanceof IfcAxis2Placement3D) {
IfcAxis2Placement3D ifcAxis2Placement3D = (IfcAxis2Placement3D) relativePlacement;
IfcObjectPlacement placementRelativeTo = ifcLocalPlacement.getPlacementRelTo();
if (placementRelativeTo == null) {
IfcCartesianPoint ifcCartesianPoint = ifcAxis2Placement3D.getLocation();
return new double[] { ifcCartesianPoint.getCoordinates().get(0).getValue(), ifcCartesianPoint.getCoordinates().get(1).getValue(), ifcCartesianPoint.getCoordinates().get(2).getValue() };
} else {
double[] relative = getAbsolutePosition(placementRelativeTo);
IfcCartesianPoint ifcCartesianPoint = ifcAxis2Placement3D.getLocation();
return new double[] { relative[0] + ifcCartesianPoint.getCoordinates().get(0).getValue(), relative[1] + ifcCartesianPoint.getCoordinates().get(1).getValue(), relative[2] + ifcCartesianPoint.getCoordinates().get(2).getValue() };
}
}
}
return new double[] { 0d, 0d, 0d };
}
参考资料:https://github.com/opensourceBIM/BIMserver/blob/master/PluginBase/src/org/bimserver/utils/IfcUtils.java#L539
警告:
this function does not take into account the directions