using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Glodon.Revit.Utility; using HStation.Model; using HStation.RevitDev.Model.AttributeClass; using HStation.RevitDev.Model.Common; using HStation.RevitDev.Model.ModelEnum; using HStation.RevitDev.RevitDataExport.Common; using HStation.RevitDev.RevitDataExport.Entity; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace HStation.RevitDev.RevitDataExport.Utility { public static class ElementExtense { public static JObject Export(this Element elem, RevitType revitType) { var exportType = ElementTypeMapping.GetExportType(revitType); var elemType = GetElementType(exportType); var ret = SetElementPropertys(elemType, elem); return ret; } private static JObject SetElementPropertys(Type elemType, Element elem) { var ret = new JObject(); var props = elemType.GetProperties(); foreach (PropertyInfo propInfo in props) { var attr = propInfo.GetCustomAttribute(); if (attr == null) { continue; } string paramName = attr.m_parameterName; ParameterUnit unit = attr.m_unit; var paramType = propInfo.PropertyType; if (!AddManualParameter(elem, ret, paramName)) { AddGeneralParameter(elem, ret, propInfo, paramName, paramType, unit); } } return ret; } private static bool AddManualParameter(Element elem, JObject ret, string paramName) { return ParameterOperator.ProcessingManualParameter(elem, ret, paramName); } private static void AddGeneralParameter(Element elem, JObject ret, PropertyInfo propInfo, string paramName, Type paramType, ParameterUnit unit) { var propType = propInfo.PropertyType; object revitParamValue = GetParameterValue(elem, paramName, propType); if (revitParamValue == null) { return; } object outParamValue; switch (paramType.Name) { case "Int32": outParamValue = revitParamValue.ConvertTo(); ret[paramName] = (int)outParamValue; break; case "Double": switch (unit) { case ParameterUnit.PU_Unknown: outParamValue = revitParamValue.ConvertTo(); ret[paramName] = (double)outParamValue; break; case ParameterUnit.PU_MM: outParamValue = revitParamValue.ConvertTo(); ret[paramName] = (double)outParamValue.InnerToMM(); break; case ParameterUnit.PU_M: break; case ParameterUnit.PU_MMM: break; case ParameterUnit.PU_Pa: break; case ParameterUnit.PU_MPa: break; default: break; } break; case "String": outParamValue = revitParamValue.ConvertTo(); ret[paramName] = (string)outParamValue; break; case "Boolean": outParamValue = revitParamValue.ConvertTo(); ret[paramName] = (bool)outParamValue; break; default: throw new Exception("未知类型!"); } } private static T ConvertTo(this object inObj) { var inTypeName = inObj.GetType().Name; var outTypeName = typeof(T).Name; switch (inTypeName) { case "String": switch (outTypeName) { case "String": return (T)inObj; case "Int32": if (int.TryParse((string)inObj, out int iValue)) { return (T)(object)iValue; } else { throw new Exception($"参数类型{inTypeName} 转换{outTypeName}异常!"); } case "Double": if (double.TryParse((string)inObj, out double dValue)) { return (T)(object)dValue; } else { throw new Exception($"参数类型{inTypeName} 转换{outTypeName}异常!"); } case "Boolean": if (bool.TryParse((string)inObj, out bool bValue)) { return (T)(object)bValue; } else { throw new Exception($"参数类型{inTypeName} 转换{outTypeName}异常!"); } default: break; } break; case "Int32": switch (outTypeName) { case "String": return (T)(object)inObj.ToString(); case "Int32": return (T)inObj; case "Double": return (T)inObj; case "Boolean": throw new Exception($"无法转换参数类型{inTypeName}到{outTypeName}!"); default: break; } break; case "Double": switch (outTypeName) { case "String": return (T)(object)inObj.ToString(); case "Int32": case "Double": return (T)inObj; case "Boolean": throw new Exception($"无法转换参数类型{inTypeName}到{outTypeName}!"); default: break; } break; case "Boolean": switch (outTypeName) { case "String": return (T)(object)inObj.ToString(); case "Int32": case "Double": case "Boolean": return (T)inObj; default: break; } break; default: return default; } return default; } private static object GetParameterValue(Element elem, string paramName, Type propType) { object paramValue = null; try { if (propType.Name == "String") { var strValue = ParameterOperator.GetParameterValueAsString(elem, paramName); paramValue = strValue == null ? string.Empty : strValue; } else if (propType.Name == "Int32") { paramValue = ParameterOperator.GetParameterValueAsInt(elem, paramName); } else if (propType.Name == "Double") { paramValue = ParameterOperator.GetParameterValueAsDouble(elem, paramName); } else if (propType.Name == "Boolean") { int? value = ParameterOperator.GetParameterValueAsInt(elem, paramName); if (value == 1) { paramValue = true; } else { paramValue = false; } } } catch (Exception ex) { return paramValue; } return paramValue; } private static Type GetElementType(ExportType exportType) { var types = Assembly.GetAssembly(typeof(RevitModel)).GetTypes(); foreach (var type in types) { var attr = type.GetCustomAttribute(); if (attr == null) { continue; } if (attr.m_exportType == exportType) { return type; } } return null; } public static Level GetLevel(this Element element) { var levelId1 = element.LevelId; if (levelId1 != null) { Level level1 = element.Document.GetElement(levelId1) as Level; return level1; } var levelParam = element.LookupParameter("标高"); if (levelParam != null) { ElementId levelId2 = levelParam.AsElementId(); if (levelId2 != null) { Level level2 = element.Document.GetElement(levelId2) as Level; return level2; } } return null; } } public static class ElementExtense2 { public static JObject Export2(this Element elem) { var ret = new JObject(); if (elem == null) { return ret; } var customDict = elem.ExportCostomDict(); foreach (var item in customDict) { ret[item.Key] = JToken.FromObject(item.Value); } elem.ExportParameters(ref ret); return ret; } public static void ExportParameters(this Element elem, ref JObject ret) { if (elem == null) { return; } var parameters = elem.Parameters; foreach (Parameter param in parameters) { var name = param.Definition.Name; switch (param.StorageType) { case StorageType.None: break; case StorageType.Integer: { int value = param.AsInteger(); ret[name] = value; break; } case StorageType.Double: { string value = param.AsValueString(); if (string.IsNullOrEmpty(value)) { value = param.AsString(); } ret[name] = value; break; } case StorageType.String: { string value = param.AsString(); ret[name] = value; break; } case StorageType.ElementId: { ElementId value = param.AsElementId(); Element subElem = elem.Document.GetElement(value); if (subElem == null) { ret[name] = null; } else { ret[name] = subElem.Export2(); } break; } default: break; } } return; } public static Dictionary ExportCostomDict(this Element elem) { if (elem == null) { return null; } var ret = new Dictionary(); ret.Add("构件编码", elem.Id.IntegerValue.ToString()); List connectors = elem.GetConnectors(); ret.Add("连接列表", connectors); return ret; } public static List GetConnectElements(this Element element) { var ret = new List(); if (element == null) { return ret; } ConnectorSet connectors = null; if (element is FamilyInstance fi) { var mepModel = fi.MEPModel; if (mepModel == null) { return ret; } connectors = mepModel.ConnectorManager?.Connectors; } else if(element is Pipe pipe) { connectors = pipe.ConnectorManager.Connectors; } else { return ret; } if (connectors == null) { return ret; } foreach (Autodesk.Revit.DB.Connector connector in connectors) { var linkedElems = connector.GetConnectorElements(); ret.AddRange(linkedElems); } return ret; } public static List GetConnectors(this Element elem) { List ret = new List(); if (elem == null) { return ret; } ConnectorManager manager = null; if (elem is Pipe pipe) { manager = pipe.ConnectorManager; } else if (elem is FamilyInstance fi) { manager = fi.MEPModel?.ConnectorManager; } if (manager == null) { return ret; } var connectors = manager.Connectors; foreach (Autodesk.Revit.DB.Connector connector in connectors) { if (connector.Domain != Domain.DomainHvac && connector.Domain != Domain.DomainPiping) { continue; } var dir = connector.Direction == FlowDirectionType.Bidirectional ? ConnectorDirction.BOTH : (connector.Direction == FlowDirectionType.In ? ConnectorDirction.IN : ConnectorDirction.OUT); List connectElems = connector.GetConnectorElements(); ret.Add(new Entity.Connector { ConnectId = connectElems.FirstOrDefault()?.Id.IntegerValue.ToString(), Dirction = dir, Point = connector.Origin.ToCustomPoint(), }); } return ret; } } }