zhangyuekai
2024-08-10 a18b907beff8b21fb4c9d6fb72678ac5e9f7b80d
HStation.RevitDev/RevitDataExport/Utility/ElementExtense.cs
@@ -1,266 +1,422 @@
using Autodesk.Revit.DB;
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 Newtonsoft.Json.Linq;
using System;
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<ParameterAttribute>();
                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<int>();
                    ret[paramName] = (int)outParamValue;
                    break;
                case "Double":
                    switch (unit)
                    {
                        case ParameterUnit.PU_Unknown:
                            outParamValue = revitParamValue.ConvertTo<double>();
                            ret[paramName] = (double)outParamValue;
                            break;
                        case ParameterUnit.PU_MM:
                            outParamValue = revitParamValue.ConvertTo<double>();
                            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<string>();
                    ret[paramName] = (string)outParamValue;
                    break;
                case "Boolean":
                    outParamValue = revitParamValue.ConvertTo<bool>();
                    ret[paramName] = (bool)outParamValue;
                    break;
                default:
                    throw new Exception("未知类型!");
            }
        }
        private static T ConvertTo<T>(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<ExportTypeAttribute>();
                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;
        }
    }
}
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<ParameterAttribute>();
                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<int>();
                    ret[paramName] = (int)outParamValue;
                    break;
                case "Double":
                    switch (unit)
                    {
                        case ParameterUnit.PU_Unknown:
                            outParamValue = revitParamValue.ConvertTo<double>();
                            ret[paramName] = (double)outParamValue;
                            break;
                        case ParameterUnit.PU_MM:
                            outParamValue = revitParamValue.ConvertTo<double>();
                            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<string>();
                    ret[paramName] = (string)outParamValue;
                    break;
                case "Boolean":
                    outParamValue = revitParamValue.ConvertTo<bool>();
                    ret[paramName] = (bool)outParamValue;
                    break;
                default:
                    throw new Exception("未知类型!");
            }
        }
        private static T ConvertTo<T>(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<ExportTypeAttribute>();
                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<string, object> ExportCostomDict(this Element elem)
        {
            if (elem == null) { return null; }
            var ret = new Dictionary<string, object>();
            ret.Add("构件编码", elem.Id.IntegerValue.ToString());
            List<Entity.Connector> connectors = elem.GetConnectors();
            ret.Add("连接列表", connectors);
            return ret;
        }
        public static List<Element> GetConnectElements(this Element element)
        {
            var ret = new List<Element>();
            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<Entity.Connector> GetConnectors(this Element elem)
        {
            List<Entity.Connector> ret = new List<Entity.Connector>();
            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<Element> connectElems = connector.GetConnectorElements();
                ret.Add(new Entity.Connector
                {
                    ConnectId = connectElems.FirstOrDefault()?.Id.IntegerValue.ToString(),
                    Dirction = dir,
                    Point = connector.Origin.ToCustomPoint(),
                });
            }
            return ret;
        }
    }
}