using Autodesk.Revit.DB; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using HStation.RevitDev.RevitDataExport; using HStation.RevitDev.RevitDataExport.Common; using HStation.RevitDev.RevitDataExport.Utility; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; namespace Glodon.Revit.Utility { public class ParameterOperator { public static bool ProcessingManualParameter(Element elem, JObject ret, string paramName) { if (paramName.ToUpper() == "名称") { var name = GetParameterValueAsString(elem, "名称"); if (string.IsNullOrEmpty(name)) { name = elem.Name; } ret["名称"] = name; return true; } else if (paramName.ToUpper() == "ID") { ret["ID"] = elem.Id.IntegerValue.ToString(); return true; } else if (paramName == "编码") { var code = GetParameterValueAsString(elem, "编码"); if (string.IsNullOrEmpty(code)) { code = elem.Id.IntegerValue.ToString(); } ret["编码"] = code; return true; } else if (paramName == "位置") { SetPosition(elem, ret); return true; } else if (paramName == "属性值列表") { SetParameters(elem, ret); return true; } else if (paramName == "上游节点编码") { return SetUpperElement(elem, ret); } else if (paramName == "下游节点编码") { return SetDownElement(elem, ret); } else if (paramName == "标签") { return SetFlag(elem, ret); } else if (paramName == "标高") { Level level = elem.GetLevel(); double offsetValue = 0; var offset = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); if (offset != null) { offsetValue = offset.AsDouble(); } ret["标高"] = (level?.Elevation + offsetValue).InnerToMM(); return true; } else if (paramName == "池底标高") { Level level = elem.GetLevel(); double offsetValue = 0; var offset = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); if (offset != null) { offsetValue = offset.AsDouble(); } ret["池底标高"] = (level?.Elevation + offsetValue).InnerToMM(); return true; } else { return false; } } private static bool SetFlag(Element elem, JObject ret) { string strFlag = GetParameterValueAsString(elem, "标签"); JArray jArray = new JArray(); if (!string.IsNullOrEmpty(strFlag)) { var flags = strFlag.Split(','); foreach (var flag in flags) { jArray.Add(new JValue(flag)); } } ret["标签"] = jArray; return true; } private static bool SetDownElement(Element elem, JObject ret) { var id = elem.Id.IntegerValue.ToString(); if (elem is FamilyInstance fi) { var mepModel = (elem as FamilyInstance)?.MEPModel; if (mepModel == null) { return false; } var ids = GetConnectElements(mepModel.ConnectorManager?.Connectors, FlowDirectionType.Out); var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray(); var retStr = string.Join(",", strIds); ret["下游节点编码"] = retStr; return true; } else if (elem is Pipe pipe) { var ids = GetConnectElements(pipe.ConnectorManager?.Connectors, FlowDirectionType.Out); var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray(); var retStr = string.Join(",", strIds); ret["下游节点编码"] = retStr; return true; } return false; } private static bool SetUpperElement(Element elem, JObject ret) { var id = elem.Id.IntegerValue.ToString(); if (elem is FamilyInstance fi) { var mepModel = (elem as FamilyInstance)?.MEPModel; if (mepModel == null) { return false; } var ids = GetConnectElements(mepModel.ConnectorManager?.Connectors, FlowDirectionType.In); var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray(); var retStr = string.Join(",", strIds); ret["上游节点编码"] = retStr; return true; } else if (elem is Pipe pipe) { var ids = GetConnectElements(pipe.ConnectorManager?.Connectors, FlowDirectionType.In); var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray(); var retStr = string.Join(",", strIds); ret["上游节点编码"] = retStr; return true; } return false; } private static void SetParameters(Element elem, JObject ret) { var parameters = elem.Parameters; JObject jObj = new JObject(); foreach (Parameter parameter in parameters) { ConvertParameter2Jobject(parameter, ref jObj); } ret["属性值列表"] = jObj; } private static void SetPosition(Element elem, JObject ret) { if (elem is Pipe pipe) { Location location = pipe.Location; LocationCurve lCurve = location as LocationCurve; Line line = lCurve.Curve as Line; XYZ st = line.GetEndPoint(0); XYZ end = line.GetEndPoint(1); XYZ center = (st + end) / 2; var minObj = new JObject(); minObj["X"] = st.X.InnerToMM(); minObj["Y"] = st.Y.InnerToMM(); minObj["Z"] = st.Z.InnerToMM(); var centerObj = new JObject(); centerObj["X"] = center.X.InnerToMM(); centerObj["Y"] = center.Y.InnerToMM(); centerObj["Z"] = center.Z.InnerToMM(); var maxObj = new JObject(); maxObj["X"] = end.X.InnerToMM(); maxObj["Y"] = end.Y.InnerToMM(); maxObj["Z"] = end.Z.InnerToMM(); var outObj = new JObject(); outObj["Min"] = minObj; outObj["Center"] = centerObj; outObj["Max"] = maxObj; ret["位置"] = outObj; } else { var box = elem.get_BoundingBox(null); var minObj = new JObject(); minObj["X"] = box.Min.X.InnerToMM(); minObj["Y"] = box.Min.Y.InnerToMM(); minObj["Z"] = box.Min.Z.InnerToMM(); var centerObj = new JObject(); if (elem is FamilyInstance fi) { if (fi.Location is LocationPoint lp) { var position = lp.Point; centerObj["X"] = position.X.InnerToMM(); centerObj["Y"] = position.Y.InnerToMM(); centerObj["Z"] = position.Z.InnerToMM(); } } var maxObj = new JObject(); maxObj["X"] = box.Max.X.InnerToMM(); maxObj["Y"] = box.Max.Y.InnerToMM(); maxObj["Z"] = box.Max.Z.InnerToMM(); var outObj = new JObject(); outObj["Min"] = minObj; outObj["Center"] = centerObj; outObj["Max"] = maxObj; ret["位置"] = outObj; } } /// /// 构件属性 /// /// /// /// /// public static Parameter GetParameterByEnum(Document doc, Element inputElement, string attributeName) { Parameter useParameter = null; try { var fi = inputElement as FamilyInstance; if (null != fi) { useParameter = fi.LookupParameter(attributeName); if (useParameter != null) { return useParameter; } useParameter = fi.Symbol.LookupParameter(attributeName); if (null != useParameter) { return useParameter; } } useParameter = inputElement.LookupParameter(attributeName); if (null != useParameter) { return useParameter; } Element element = doc.GetElement(inputElement.GetTypeId()); if (null != element) { useParameter = element.LookupParameter(attributeName); if (null != useParameter) { return useParameter; } } } catch (Exception) { } return null; } public static List GetConnectElements(ConnectorSet connectors, FlowDirectionType direction) { if (connectors == null || connectors.Size == 0) { return null; } var retIds = new List(); foreach (Connector connector in connectors) { if (!connector.IsConnected || (connector.ConnectorType != ConnectorType.End && connector.ConnectorType != ConnectorType.Curve && connector.ConnectorType != ConnectorType.Physical)) { continue; } if (connector.Direction == direction) { var refElems = connector.AllRefs; foreach (Connector item in refElems) { if (!connector.IsConnected || (connector.ConnectorType != ConnectorType.End && connector.ConnectorType != ConnectorType.Curve && connector.ConnectorType != ConnectorType.Physical)) { continue; } var owner = item.Owner; if (owner.Id != connector.Owner.Id) { if (owner is PipingSystem) { continue; } else { retIds.Add(item.Owner.Id); } } } } } return retIds; } public static PipingSystemType GetElementPipingSystemType(Element elem) { if (elem is Pipe pipe) { var mepSystem = pipe.MEPSystem; if (mepSystem == null) { return null; } var typeId = mepSystem.GetTypeId(); return elem.Document.GetElement(typeId) as PipingSystemType; } else if (elem is FamilyInstance fi) { var parameter = fi.LookupParameter("系统类型"); if (parameter == null) { return null; } if (parameter.StorageType == StorageType.String) { var name = parameter.AsString(); var pst = new FilteredElementCollector(elem.Document).OfClass(typeof(PipingSystemType)).ToElements()?.Cast().ToList()?.Find(x => x.Name == name); return pst; } else if (parameter.StorageType == StorageType.ElementId) { var elemId = parameter.AsElementId(); return elem.Document.GetElement(elemId) as PipingSystemType; } } return null; } /// /// 获取属性 /// /// /// /// /// public static Parameter GetParameter(Document doc, Element inputElement, string attributeName) { return GetParameterByEnum(doc, inputElement, attributeName); } /// /// 获取属性值 /// /// /// public static string GetParemeterValue(Parameter parameter) { if (parameter == null) { return string.Empty; } var result = string.Empty; if (parameter.StorageType == StorageType.Integer) { result = parameter.AsInteger().ToString(); } else if (parameter.StorageType == StorageType.Double) { result = parameter.AsDouble().ToString(); } else if (parameter.StorageType == StorageType.ElementId) { result = parameter.AsValueString(); } else { result = string.IsNullOrWhiteSpace(parameter.AsString()) ? parameter.AsValueString() : parameter.AsString(); } if (result == null) { return string.Empty; } return result; } /// /// 获取名称属性值 /// /// /// /// /// public static string GetElementName(Element eachElement) { try { //获取实例 族与类型 参数值 Parameter param = eachElement.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM); string value = GetParemeterValue(param); if (!string.IsNullOrEmpty(value)) { return value; } return eachElement.Name; } catch (Exception) { return string.Empty; } } /// /// 获取族与类型参数 /// /// public static string GetElementFamilyAndTypeValue(Element eachElement) { try { //获取实例 族与类型 参数值 Parameter param = eachElement.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM); string value = GetParemeterValue(param); if (!string.IsNullOrEmpty(value)) { return value; } //如 族与类型 获取失败,只提取类型名称 var type = eachElement.Document.GetElement(eachElement.GetTypeId()); return type == null ? string.Empty : type.Name; } catch (Exception) { return string.Empty; } } /// /// 属性值是否可用 /// /// /// /// private static bool ExtractParameter(IList lstParametet, out string paraValue) { paraValue = string.Empty; foreach (var item in lstParametet) { var value = GetParemeterValue(item); var succeed = value != null && !string.IsNullOrWhiteSpace(value) && value != "0"; if (succeed) { paraValue = value; return succeed; } } return false; } /// /// 是否为mep构件 /// /// private static bool IsMEPInstace(BuiltInCategory instanceCategory) { switch (instanceCategory) { case BuiltInCategory.OST_DuctSystem: case BuiltInCategory.OST_PipingSystem: return true; default: return false; } } public static string GetPipeSystemTypeName(Pipe pipe) { try { var parameter = pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM); return parameter.AsValueString(); } catch (Exception) { return string.Empty; } } public static string GetDuctSystemTypeName(Duct duct) { try { var parameter = duct.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM); if (parameter == null) { return null; } return parameter.AsValueString(); } catch (Exception) { return string.Empty; } } /// /// 获取参数值 AsDouble /// /// /// /// public static double? GetParameterValueAsDouble(Element elem, BuiltInParameter builtInParameter) { double? result = null; if (elem != null && elem.get_Parameter(builtInParameter) is Parameter para) { if (para == null || !para.HasValue) { return result; } result = para.AsDouble(); } return result; } /// /// 获取参数值 AsDouble /// /// /// /// 单位转换方法 /// public static double? GetParameterValueAsDouble(Element elem, string paramName, Func innerTo = null) { double? result = null; if (elem != null) { try { Parameter para = elem.GetParameterByProName(paramName); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: break; case StorageType.Integer: result = para.AsInteger(); break; case StorageType.Double: //if (innerTo != null && para.GetUnitTypeId() != UnitTypeId.General) if (innerTo != null && para.DisplayUnitType != DisplayUnitType.DUT_GENERAL) { result = innerTo(para.AsDouble()); } else { result = para.AsDouble(); } break; case StorageType.String: result = StringToDouble(para.AsString()); break; case StorageType.ElementId: //不处理 break; default: break; } } catch (Exception ex) { return result; } } return result; } /// /// 获取参数值 AsDouble /// /// /// /// /// public static double? GetParameterValueAsDouble(Element elem, string[] paramNames, Func innerTo = null) { double? result = null; foreach (var paramName in paramNames) { var res = GetParameterValueAsDouble(elem, paramName, innerTo); if (res != null) { result = res; break; } } return result; } /// /// 获取参数值 AsString /// /// /// /// public static string GetParameterValueAsString(Element elem, string paramName) { string result = string.Empty; if (elem != null) { Parameter para = elem.GetParameterByProName(paramName); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: result = para.AsString(); break; case StorageType.Integer: result = para.AsInteger().ToString(); break; case StorageType.Double: result = para.AsValueString(); break; case StorageType.String: result = para.AsString(); break; case StorageType.ElementId: result = para.AsElementId().IntegerValue.ToString(); break; default: break; } } return result; } /// /// 获取参数值 AsValueString /// /// /// /// public static string GetParameterValueAsValueString(Element elem, string paramName) { string result = null; if (elem != null) { Parameter para = elem.GetParameterByProName(paramName); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: result = para.AsString(); break; case StorageType.Integer: result = para.AsInteger().ToString(); break; case StorageType.Double: result = para.AsValueString(); break; case StorageType.String: result = para.AsString(); break; case StorageType.ElementId: result = para.AsElementId().IntegerValue.ToString(); break; default: break; } } return result; } /// /// 获取参数值 AsDouble /// /// /// /// /// 单位转换方法 /// public static double? GetParameterValueAsDouble(Element elem, string paramName, BuiltInParameter builtInParameter, Func innerTo = null) { double? result = null; try { if (elem != null) { Parameter para = elem.GetParameter(paramName, builtInParameter); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: break; case StorageType.Integer: result = para.AsInteger(); break; case StorageType.Double: //if (innerTo != null && para.GetUnitTypeId() != UnitTypeId.General)//传入了单位转换方法 且参数设置了单位 if (innerTo != null && para.DisplayUnitType != DisplayUnitType.DUT_GENERAL) { result = innerTo(para.AsDouble()); } else { result = para.AsDouble(); } break; case StorageType.String: result = StringToDouble(para.AsString()); break; case StorageType.ElementId: //不处理 break; default: break; } } } catch (Exception ex) { return null; } return result; } /// /// 获取参数值 AsString /// /// /// /// public static void ConvertParameter2Jobject(Parameter para, ref JObject jObj) { var name = para.Definition.Name; if (para != null) { switch (para.StorageType) { case StorageType.Integer: var intRet = para.AsInteger(); jObj[name] = intRet; break; case StorageType.Double: var doubleRet = para.AsDouble(); jObj[name] = doubleRet; break; case StorageType.String: var strRet = para.AsString(); jObj[name] = strRet; break; case StorageType.ElementId: var elemIdRet = para.AsElementId().IntegerValue; jObj[name] = elemIdRet; break; case StorageType.None: default: jObj[name] = null; break; } } return; } /// /// 值是字符串,可能是由是数字+单位组成,也可能没有单位 /// /// /// private static double? StringToDouble(string str) { double? value = null; if (string.IsNullOrWhiteSpace(str)) return value; Regex r = new Regex(@"([+-]?(\d*\.\d+([eE]?[+-]?\d+)?|\d+[eE][+-]?\d+))|([+-]?\d*)|([1-9]\d*\.?\d*)|(0\.\d*[1-9])"); //开始匹配 Match m = r.Match(str); string newStr = ""; while (m.Success) { //匹配成功 newStr += m.Groups[0].Value; //从上一个匹配结束的位置开始下一个匹配 m = m.NextMatch(); } if (newStr == "") { return value; } value = Convert.ToDouble(newStr); return value; } /// /// 获取参数值 AsString /// /// /// /// /// public static string GetParameterValueAsString(Element elem, string paramName, BuiltInParameter builtInParameter) { string result = null; if (elem != null) { Parameter para = elem.GetParameter(paramName, builtInParameter); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: result = para.AsString(); break; case StorageType.Integer: result = para.AsInteger().ToString(); break; case StorageType.Double: result = para.AsValueString(); break; case StorageType.String: result = para.AsString(); break; case StorageType.ElementId: result = para.AsElementId().IntegerValue.ToString(); break; default: break; } } return result; } /// /// 获取参数值 AsValueString /// /// /// /// /// public static string GetParameterValueAsValueString(Element elem, string paramName, BuiltInParameter builtInParameter) { string result = null; if (elem != null) { Parameter para = elem.GetParameter(paramName, builtInParameter); if (para == null || !para.HasValue) { return result; } result = para.AsValueString(); } return result; } /// /// 获取参数值 AsInt /// /// /// /// /// public static int? GetParameterValueAsInt(Element elem, string paramName, BuiltInParameter builtInParameter) { int? result = null; if (elem != null) { Parameter para = elem.GetParameter(paramName, builtInParameter); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: break; case StorageType.Integer: result = para.AsInteger(); break; case StorageType.Double: //不处理 break; case StorageType.String: break; case StorageType.ElementId: result = para.AsElementId().IntegerValue; break; default: break; } } return result; } /// /// 获取参数值 AsInt /// /// /// /// /// public static int? GetParameterValueAsInt(Element elem, string paramName) { int? result = null; if (elem != null) { Parameter para = elem.GetParameterByProName(paramName); if (para == null || !para.HasValue) { return result; } switch (para.StorageType) { case StorageType.None: break; case StorageType.Integer: result = para.AsInteger(); break; case StorageType.Double: { var ret = para.AsDouble(); result = (int)ret; break; } case StorageType.String: { var str = para.AsString(); if (int.TryParse(str, out int ret)) { return ret; } break; } case StorageType.ElementId: result = para.AsElementId().IntegerValue; break; default: break; } } return result; } /// /// 获取参数值 AsElementId /// /// /// /// /// public static ElementId GetParameterValueAsElementId(Element elem, string paramName, BuiltInParameter builtInParameter) { ElementId result = null; if (elem != null) { Parameter para = elem.GetParameter(paramName, builtInParameter); if (para == null || !para.HasValue) { return result; } result = para.AsElementId(); } return result; } /// /// 获取参数值 AsElementId /// /// /// /// /// public static ElementId GetParameterValueAsElementId(Element elem, BuiltInParameter builtInParameter) { ElementId result = null; if (elem != null) { Parameter para = elem.get_Parameter(builtInParameter); if (para == null || !para.HasValue) { return result; } result = para.AsElementId(); } return result; } /// /// 获取参数值 AsElementId /// /// /// /// /// public static ElementId GetParameterValueAsElementId(Element elem, string paramName) { ElementId result = null; if (elem != null) { Parameter para = elem.GetParameterByProName(paramName); if (para == null || !para.HasValue) { return result; } result = para.AsElementId(); } return result; } /// /// 获取系统类型名称字符串 /// /// /// /// /// public static string GetSystemTypeName(Element elem, string paramName, BuiltInParameter builtInParameter = BuiltInParameter.INVALID) { string res = null; try { if (builtInParameter != BuiltInParameter.INVALID) { Parameter para = elem.GetParameter(paramName, builtInParameter); if (para != null) { if (para.StorageType == StorageType.ElementId) { var elemId = para.AsElementId(); if (elemId != null && elemId != ElementId.InvalidElementId) { var tempElem = elem.Document.GetElement(elemId); res = tempElem.Name; } } else { res = para.AsValueString(); } } } else { Parameter para = elem.GetParameterByProName(paramName); if (para != null) { if (para.StorageType == StorageType.ElementId) { var elemId = para.AsElementId(); if (elemId != null && elemId != ElementId.InvalidElementId) { var tempElem = elem.Document.GetElement(elemId); res = tempElem.Name; } } else { res = para.AsValueString(); } } } } catch { } return res; } } public static class ParameterUtil { /// /// 有内置参数的,调用该函数 /// /// /// 参数名 /// 内置参数 /// public static Parameter GetParameter(this Element element, string parameterName, BuiltInParameter builtInParameter) { Parameter para = null; try { if (element is ElementType) { para = element.get_Parameter(builtInParameter); } else { para = element.get_Parameter(builtInParameter); if (para == null) { var typeId = element.GetTypeId(); if (typeId == null) { return null; } var type = element.Document.GetElement(typeId) as ElementType; para = type.get_Parameter(builtInParameter); } } } catch (Exception ex) { para = null; } return para == null ? GetParameterByProName(element, parameterName) : para; } /// /// 根据参数名获取参数,如果element是类型,获取的就是类型参数, /// 如果element是实例,先获取实例参数,如果获取不到,就获取类型参数,实例参数优先 /// 如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的 /// /// /// /// public static Parameter GetParameterByProName(this Element element, string parameterName) { if (element is ElementType elementType) { return GetParameterByName(elementType, parameterName); } else { var result = GetParameterByName(element, parameterName); if (result != null) { return result; } var typeId = element.GetTypeId(); if (typeId == null || typeId == ElementId.InvalidElementId) { return null; } var type = element.Document.GetElement(typeId) as ElementType; return GetParameterByName(type, parameterName); } } /// /// 根据参数名获取参数,如果element是类型,获取的就是类型参数, /// 如果element是实例,先获取实例参数,如果获取不到,就获取类型参数,实例参数优先 /// 如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的 /// /// /// 参数名称列表【有一个匹配则直接返回】 /// public static Parameter GetParameterByProName(this Element element, List paramNames) { Parameter ret = null; foreach (var parameterName in paramNames) { if (element is ElementType elementType) { ret = GetParameterByName(elementType, parameterName); if (ret == null) { continue; } } else { var result = GetParameterByName(element, parameterName); if (result != null) { return result; } var typeId = element.GetTypeId(); if (typeId == null || typeId == ElementId.InvalidElementId) { continue; } var type = element.Document.GetElement(typeId) as ElementType; ret = GetParameterByName(type, parameterName); if (ret == null) { continue; } } if (ret != null) { return ret; } } return null; } /// /// 根据参数名获取,如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的 /// /// /// /// private static Parameter GetParameterByName(this Element element, string parameterName) { if (string.IsNullOrEmpty(parameterName)) { return null; } var parameters = element.GetParameters(parameterName); if (parameters.Count == 0) { return null; } if (parameters.Count == 1) { return parameters[0]; } //如果参数有多个,获取有值的参数 var tempParams = parameters.Where(x => !string.IsNullOrEmpty(ParameterOperator.GetParemeterValue(x))).ToList(); //如果多个参数都没有值 则返回第一个 if (tempParams.Count == 0) { return parameters.First(); } //如果只有一个参数有值 则返回这个参数 if (tempParams.Count == 1) { return tempParams.First(); } return tempParams.First(); } } }