Revit API开发中如何获取圆柱形族实例插入点的Z坐标
Revit API 获取圆柱形族实例插入点Z坐标异常问题
本文为Revit API论坛帖子副本
问题背景
- 项目中存在多个圆柱体族实例,创建代码如下:
FamilyInstance element = document.Create.NewFamilyInstance(location, symbol, StructuralType.NonStructural); - 创建实例时传入的位置参数仅包含X、Y坐标,Z坐标固定为
0.0,示例坐标为(-6.2, 65.6, 0.0) - 圆柱形族实例的长度由
Depth参数控制,Z方向上前一个实例的终点即为后一个实例的起点 - 实例创建完成后需要提取族插入点的完整XYZ坐标,用于后续创建地形曲面、连接同类型族实例
- 现有代码运行后仅能获取X、Y坐标,Z坐标始终返回
0.0
现有实现代码
// 对geo_famtyp_names列表去重 List<string> distinct_geo_famtyp_names = geo_famtyp_names.Distinct().ToList(); // 遍历列表中所有类型名称,获取对应元素集合并执行后续逻辑 foreach (string typename in distinct_geo_famtyp_names) { List<XYZ> positions = new List<XYZ>(); var paramId = new ElementId(BuiltInParameter.SYMBOL_FAMILY_AND_TYPE_NAMES_PARAM); var fam_type = String.Format("{0}: {1}", "BAUER_Fam_GeologyLayer", typename); var rule = ParameterFilterRuleFactory.CreateEqualsRule(paramId, fam_type, true); var filter = new ElementParameterFilter(rule); var elem_collec = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).WherePasses(filter).ToList(); // 收集指定族类型下所有元素的位置 foreach (FamilyInstance el in elem_collec) { XYZ elem_pos = ((LocationPoint)el.Location).Point; if (!(positions.Contains(elem_pos))) { positions.Add(elem_pos); } } }
原因说明
((LocationPoint)el.Location).Point返回的是族实例的基准插入点,也就是创建实例时传入的初始坐标。创建实例时Z值传的是0,后续通过Depth参数堆叠产生的Z向偏移不会自动更新到LocationPoint的Z属性中,所以直接读取该属性永远拿到Z=0的结果。
解决方法
方法1:按堆叠逻辑计算Z值
同X、Y坐标下的实例沿Z轴堆叠,每个实例的实际插入点Z值为其下方所有同点位实例的Depth参数值总和:
- 先按X、Y坐标对所有实例分组,同一钻孔位置的实例归为一组
- 每组内的实例按Z向堆叠顺序排序(最底部的实例排第一位)
- 第一位实例Z值为0,第二位实例Z值为第一位实例的
Depth转换为实际长度后的值,第三位实例Z值为前两位实例Depth值之和,依次累加即可 - 注意参数单位转换:Revit API内部长度单位为英尺,若建模时使用公制单位,需要将读取到的
Depth参数值做对应换算
方法2:直接读取实例几何的实际坐标
不依赖插入点属性,直接提取实例的最终显示几何,取圆柱体底面中心点作为实际插入点,该坐标已经包含所有参数驱动、位置变换后的结果,参考代码:
Options geoOptions = new Options(); geoOptions.DetailLevel = ViewDetailLevel.Fine; geoOptions.IncludeNonVisibleObjects = false; GeometryElement geoElement = el.get_Geometry(geoOptions); foreach (GeometryObject geoObj in geoElement) { Solid solid = geoObj as Solid; if (solid == null || solid.Volume < 1e-6) continue; // 遍历实体面,找到朝下的圆柱底面 foreach (Face face in solid.Faces) { PlanarFace planarFace = face as PlanarFace; if (planarFace == null) continue; // 法向量朝下(Z值接近-1)的面即为圆柱底面 if (Math.Abs(planarFace.Normal.Z + 1) < 1e-6) { XYZ actualInsertPoint = planarFace.Origin; break; } } }
如果族存在嵌套、剪切或连接操作,需要对应调整几何提取选项,确保拿到的是最终显示的实体几何。
内容的提问来源于stack exchange,提问作者must
相关产品推荐
相关产品推荐

