瀏覽代碼

xls:扩展数据方法扩展

xulisong 6 年之前
父節點
當前提交
624cdcfc5e

+ 28 - 0
MBI/SAGA.MBI/TestCommand.cs

@@ -33,6 +33,7 @@ using SAGA.MBI.WinView.Login;
 using SAGA.MBI.WinView.Upload;
 using SAGA.RevitUtils;
 using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.ExtensibleStorage;
 using SAGA.RevitUtils.MEP;
 using WPfPointInfo;
 using Color = Autodesk.Revit.DB.Color;
@@ -515,6 +516,33 @@ namespace SAGA.MBI
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {
+            var document = ExternalDataWrapper.Current.Doc;
+            using (Transaction tran = new Transaction(document, "版本测试"))
+            {
+                tran.Start();
+                try
+                {
+                    var infoOld = ExternalDataWrapper.Current.Doc.ProjectInformation.GetSimpleClass<ModelFileInformation>();
+                    if (infoOld == null)
+                    {
+                        infoOld = new ModelFileInformation() { ProjectId = "pj1" };
+                    }
+                    else
+                    {
+                        infoOld.ProjectId = infoOld.ProjectId + "a";
+                    }
+                    ExternalDataWrapper.Current.Doc.ProjectInformation.SetSimpleClass(infoOld);
+                    tran.Commit();
+                }
+                catch (Exception e)
+                {
+                    tran.RollBack();
+                    MessageShow.Infomation(string.Format("{0}:失败", e.ToString()));
+                }
+            }
+
+           
+            return Result.Succeeded;
             var result = System.Windows.Forms.DialogResult.No;//MessageShow.Question2("是修改整个项目(【是】整个项目;【否】当前打开模型)");
             switch (result)
             {

+ 188 - 2
MBI/SAGA.RevitUtils/ExtensibleStorage/ElementDataStorage.cs

@@ -12,6 +12,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Windows.Forms;
 using Autodesk.Revit.DB;
 using Autodesk.Revit.DB.ExtensibleStorage;
@@ -47,8 +48,10 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                 {
                     fieldBuilder.SetUnitType(UnitType.UT_Number);
                 }
+
                 schema = schemaBuilder.Finish();
             }
+
             Entity entity = new Entity(schema);
             Field field = schema.GetField(dataEnum.ToString());
             if (isDouble || isXyz)
@@ -59,6 +62,7 @@ namespace SAGA.RevitUtils.ExtensibleStorage
             {
                 entity.Set<T>(field, value);
             }
+
             element.SetEntity(entity);
         }
 
@@ -87,14 +91,17 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                 {
                     fieldBuilder.SetUnitType(UnitType.UT_Number);
                 }
+
                 schema = schemaBuilder.Finish();
             }
+
             Entity entity = new Entity(schema);
             Field field = schema.GetField(dataEnum.ToString());
             if (isDouble || isXyz)
             {
                 entity.Set<IList<T>>(field, values, DisplayUnitType.DUT_GENERAL);
             }
+
             entity.Set<IList<T>>(field, values);
             try
             {
@@ -134,14 +141,17 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                 {
                     fieldBuilder.SetUnitType(UnitType.UT_Number);
                 }
+
                 schema = schemaBuilder.Finish();
             }
+
             Entity entity = new Entity(schema);
             Field field = schema.GetField(dataEnum.ToString());
             if (isDouble || isXyz)
             {
                 entity.Set<IDictionary<T, TU>>(field, dict, DisplayUnitType.DUT_GENERAL);
             }
+
             entity.Set<IDictionary<T, TU>>(field, dict);
             element.SetEntity(entity);
         }
@@ -165,6 +175,7 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                     return entity.Get<T>(field, DisplayUnitType.DUT_GENERAL);
                 return entity.Get<T>(field);
             }
+
             return default(T);
         }
 
@@ -182,7 +193,8 @@ namespace SAGA.RevitUtils.ExtensibleStorage
             {
                 Entity entity = element.GetEntity(schema);
                 Field field = schema.GetField(dataEnum.ToString());
-                if (typeof(T) == typeof(double) || typeof(T) == typeof(XYZ)) return entity.Get<IList<T>>(field, DisplayUnitType.DUT_GENERAL).ToList();
+                if (typeof(T) == typeof(double) || typeof(T) == typeof(XYZ))
+                    return entity.Get<IList<T>>(field, DisplayUnitType.DUT_GENERAL).ToList();
                 try
                 {
                     return entity.Get<IList<T>>(field).ToList();
@@ -193,6 +205,7 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                 }
 
             }
+
             return null;
         }
 
@@ -217,8 +230,10 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                 {
                     return entity.Get<IDictionary<T, TU>>(field, DisplayUnitType.DUT_GENERAL) as Dictionary<T, TU>;
                 }
+
                 return entity.Get<IDictionary<T, TU>>(field) as Dictionary<T, TU>;
             }
+
             return null;
         }
 
@@ -235,7 +250,7 @@ namespace SAGA.RevitUtils.ExtensibleStorage
         /// </summary>
         /// <param name="element"></param>
         /// <param name="dataEnum"></param>
-        public static void DeleteStorageData(this Element element,Enum dataEnum)
+        public static void DeleteStorageData(this Element element, Enum dataEnum)
         {
             Schema schema = Schema.Lookup(dataEnum.GetGuid());
             if (schema != null)
@@ -243,5 +258,176 @@ namespace SAGA.RevitUtils.ExtensibleStorage
                 element.DeleteEntity(schema);
             }
         }
+
+        /// <summary>
+        /// 存储简单对象数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="element"></param>
+        /// <param name="value"></param>
+        public static void SetSimpleClass<T>(this Element element, T value)
+        {
+            var useType = typeof(T);
+            Guid guid = useType.GUID;
+            Schema schema = Schema.Lookup(guid);
+
+            #region 初始化属性集合
+
+            List<Tuple<string, Type, object>> useProperties = new List<Tuple<string, Type, object>>();
+            if (ExtensibleStorageUtil.IsCoustomStorage(useType))
+            {
+                var useValue = ((ICoustomStorage) value).GetStorage();
+                var propertyType = useValue.GetType();
+                useProperties.Add(new Tuple<string, Type, object>(useType.Name, propertyType, useValue));
+            }
+            else
+            {
+                var properties = useType.GetProperties();
+                foreach (var propertyInfo in properties)
+                {
+                    var propertyType = propertyInfo.PropertyType;
+                    var useValue = propertyInfo.GetValue(value);
+                    useProperties.Add(new Tuple<string, Type, object>(propertyInfo.Name, propertyType, useValue));
+                }
+            }
+
+            #endregion
+
+            #region 创建结构
+            if (schema == null)
+            {
+                #region 创建Schema
+
+                SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
+                schemaBuilder.SetReadAccessLevel(AccessLevel.Public);
+                schemaBuilder.SetWriteAccessLevel(AccessLevel.Public);
+                schemaBuilder.SetSchemaName(useType.Name);
+
+                #endregion
+
+                foreach (var item in useProperties)
+                {
+                    var propertyType = item.Item2;
+                    if (ExtensibleStorageUtil.IsEffectiveContent(propertyType))
+                    {
+                        FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField(item.Item1, propertyType);
+                    }
+                    else if (ExtensibleStorageUtil.IsEffectiveArray(propertyType, out Type arryContentType))
+                    {
+                        FieldBuilder fieldBuilder = schemaBuilder.AddArrayField(item.Item1, arryContentType);
+                    }
+                    else if (ExtensibleStorageUtil.IsEffectiveMap(propertyType, out Type keyType, out Type valueType))
+                    {
+                        FieldBuilder fieldBuilder = schemaBuilder.AddMapField(item.Item1, keyType, valueType);
+                    }
+                }
+
+                schema = schemaBuilder.Finish();
+            }
+            #endregion
+
+            #region 创建对象
+            Entity entity = new Entity(schema);
+            var method = ExtensibleStorageUtil.GetEntitySetMethod();
+            foreach (var item in useProperties)
+            {
+                var field = schema.GetField(item.Item1);
+                if (field == null)
+                    continue;
+                var fieldType = ExtensibleStorageUtil.GetFileType(field);
+                MethodInfo mi = method.MakeGenericMethod(fieldType);
+                var useValue = item.Item3;
+                if (useValue != null)
+                {
+                    mi.Invoke(entity, new object[] { item.Item1,useValue });
+                }
+            }
+            #endregion
+            element.SetEntity(entity);
+        }
+
+        /// <summary>
+        /// 获取简单对象数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="element"></param>
+        public static T GetSimpleClass<T>(this Element element)
+        {
+            var useType = typeof(T);
+            Guid guid = useType.GUID;
+            Schema schema = Schema.Lookup(guid);
+            if (schema == null)
+            {
+                return default(T);
+            }            
+            Entity entity = element.GetEntity(schema);
+            if (entity?.Schema == null)
+            {
+                return default(T);
+            }
+            var fields = schema.ListFields();
+            #region 创建实体对象
+            T result = default(T);
+            if (fields.Any())
+            {
+                var cons = useType.GetConstructor(Type.EmptyTypes);
+                if (cons != null)
+                {
+                    result = (T)cons.Invoke(null);
+                }
+            }
+
+            if (result == null)
+            {
+                return default(T);
+            }
+            #endregion
+
+            var getMethod = typeof(Entity).GetMethod("Get", new Type[] {typeof(string)});
+            if (ExtensibleStorageUtil.IsCoustomStorage(useType))
+            {
+                var field=fields.FirstOrDefault(f => f.FieldName == useType.Name);
+                if (field != null)
+                {
+                    var useValueType = field.ValueType;
+                    if (field.ContainerType == ContainerType.Array)
+                    {
+                        useValueType = typeof(IList<>).MakeGenericType(field.ValueType);
+                    }
+                    else if (field.ContainerType == ContainerType.Map)
+                    {
+                        useValueType = typeof(IDictionary<,>).MakeGenericType(field.KeyType,field.ValueType);
+                    }
+                    MethodInfo mi = getMethod.MakeGenericMethod(useValueType);
+                    var useValue = mi.Invoke(entity, new object[] { field.FieldName});
+                    ((ICoustomStorage)result).SetStorage(useValue);
+                }        
+            }
+            else
+            {
+                foreach (var field in fields)
+                {
+                    try
+                    {
+                        var property = useType.GetProperty(field.FieldName);
+
+                        if (property != null)
+                        {
+                            MethodInfo mi = getMethod.MakeGenericMethod(property.PropertyType);
+                            var useValue = mi.Invoke(entity, null);
+                            property.SetValue(result, useValue);
+                        }
+                    }
+                    catch (Exception)
+                    {
+
+
+                    }
+                }
+
+            }
+
+            return result;
+        }
     }
 }

+ 173 - 0
MBI/SAGA.RevitUtils/ExtensibleStorage/ExtensibleStorageUtil.cs

@@ -0,0 +1,173 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ExtensibleStorageUtil
+ * 作者:xulisong
+ * 创建时间: 2019/7/1 9:39:17
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using Autodesk.Revit.DB;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB.ExtensibleStorage;
+
+namespace SAGA.RevitUtils.ExtensibleStorage
+{
+    /// <summary>
+    /// 扩展存储工具类
+    /// </summary>
+    public class ExtensibleStorageUtil
+    {
+        /// <summary>
+        /// 扩展数据内容兼容类型
+        /// </summary>
+        private static HashSet<Type> ContentTypes { get; set; } = new HashSet<Type>();
+        /// <summary>
+        /// 扩展数据键值兼容类型
+        /// </summary>
+        private static HashSet<Type> KeyTypes { get; set; } = new HashSet<Type>();
+
+        static ExtensibleStorageUtil()
+        {
+            InitData();
+        }
+
+        private static void InitData()
+        {
+            #region 内容类型
+            ContentTypes.Add(typeof(bool));
+            ContentTypes.Add(typeof(byte));
+            ContentTypes.Add(typeof(Int16));
+            ContentTypes.Add(typeof(Int32));
+            ContentTypes.Add(typeof(float));
+            ContentTypes.Add(typeof(double));
+            ContentTypes.Add(typeof(ElementId));
+            ContentTypes.Add(typeof(Guid));
+            ContentTypes.Add(typeof(string));
+            ContentTypes.Add(typeof(XYZ));
+            ContentTypes.Add(typeof(UV));
+            ContentTypes.Add(typeof(Entity));
+            #endregion
+
+            #region 键值类型
+            KeyTypes.Add(typeof(bool));
+            KeyTypes.Add(typeof(byte));
+            KeyTypes.Add(typeof(Int16));
+            KeyTypes.Add(typeof(Int32));
+            KeyTypes.Add(typeof(ElementId));
+            KeyTypes.Add(typeof(Guid));
+            KeyTypes.Add(typeof(string));
+            #endregion
+           
+        }
+        /// <summary>
+        /// 判定是否是有效的content类型
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static bool IsEffectiveContent(Type type)
+        {
+            return ContentTypes.Contains(type);
+        }
+        /// <summary>
+        /// 判定是否是有效的key类型
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static bool IsEffectiveKey(Type type)
+        {
+            return KeyTypes.Contains(type);
+        }
+
+        public static bool IsEffectiveArray(Type type,out Type contentType)
+        {
+            contentType = null;
+            var baseType = type.GetInterface(typeof(IList<>).FullName);
+            if (baseType == null)
+            {
+                return false;
+            }
+
+            var firstType = baseType.GetGenericArguments()?.FirstOrDefault();
+            var flag= firstType != null && IsEffectiveContent(firstType);
+            if (flag)
+            {
+                contentType = firstType;
+            }
+
+            return flag;
+        }
+        public static bool IsEffectiveMap(Type type,out Type outKeyType,out Type outValueTYpe)
+        {
+            outKeyType = null;
+            outValueTYpe = null;
+            var baseType = type.GetInterface(typeof(IDictionary<,>).FullName);
+            if (baseType == null)
+            {
+                return false;
+            }
+
+            var keyType = baseType.GetGenericArguments()?.FirstOrDefault();
+            var valueType = baseType.GetGenericArguments()?.FirstOrDefault();
+
+            var flag= keyType != null && valueType != null && IsEffectiveKey(keyType) && IsEffectiveContent(valueType);
+            if (flag)
+            {
+                outKeyType = keyType;
+                outValueTYpe = valueType;
+            }
+            return flag;
+        }
+
+        /// <summary>
+        /// 是否为自定义解析存储
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static bool IsCoustomStorage(Type type)
+        {
+            var baseType = type.GetInterface(typeof(ICoustomStorage).FullName);
+            return baseType != null;
+        }
+        /// <summary>
+        /// 获取可用set方法
+        /// </summary>
+        /// <returns></returns>
+        public static MethodInfo GetEntitySetMethod()
+        {
+            var methods= typeof(Entity).GetMethods(BindingFlags.Public | BindingFlags.Instance);
+            foreach (var methodInfo in methods)
+            {
+                if (methodInfo.Name != "Set")
+                {
+                    continue;
+                }
+
+                var parameters = methodInfo.GetParameters();
+                if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string))
+                {
+                    return methodInfo;
+                }
+            }
+            return null;
+        }
+
+        public static Type GetFileType(Field field)
+        {
+            var useType = field.ValueType;
+            if (field.ContainerType == ContainerType.Array)
+            {
+                useType = typeof(IList<>).MakeGenericType(field.ValueType);
+            }
+            else if (field.ContainerType == ContainerType.Map)
+            {
+                useType = typeof(IDictionary<,>).MakeGenericType(field.KeyType, field.ValueType);
+            }
+            return useType;
+        }
+    }
+}

+ 21 - 0
MBI/SAGA.RevitUtils/ExtensibleStorage/ICoustomStorage.cs

@@ -0,0 +1,21 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ICoustomParseStorage
+ * 作者:xulisong
+ * 创建时间: 2019/7/1 11:12:47
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.RevitUtils.ExtensibleStorage
+{
+    public interface ICoustomStorage
+    {
+        void SetStorage(object value);
+        object GetStorage();
+    }
+}

+ 44 - 0
MBI/SAGA.RevitUtils/ExtensibleStorage/ModelFileInformation.cs

@@ -0,0 +1,44 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ModelFileInformation
+ * 作者:xulisong
+ * 创建时间: 2019/7/1 11:47:42
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.RevitUtils.ExtensibleStorage
+{
+    /// <summary>
+    /// 模型文件信息
+    /// </summary>
+    public class ModelFileInformation: ICoustomStorage
+    {
+        public string FileId { get; set; }
+        public string ProjectId { get; set; }
+        public string Version { get; set; }
+
+        public object GetStorage()
+        {
+            Dictionary<string, string> dic = new Dictionary<string, string>();
+            dic["FileId"] = FileId ?? string.Empty;
+            dic["ProjectId"] = ProjectId ?? string.Empty;
+            dic["Version"] = Version ?? string.Empty;
+            return dic;
+        }
+
+        public void SetStorage(object value)
+        {
+            if (value is IDictionary<string, string> dic)
+            {
+                this.FileId = dic["FileId"];
+                this.ProjectId = dic["ProjectId"];
+                this.Version = dic["Version"];
+            }
+        }
+    }
+}

+ 3 - 0
MBI/SAGA.RevitUtils/SAGA.RevitUtils.csproj

@@ -255,6 +255,9 @@
     <Compile Include="Extends\XYZExtend.cs" />
     <Compile Include="ExtensibleStorage\ElementDataStorage.cs" />
     <Compile Include="ExtensibleStorage\EnumDefination.cs" />
+    <Compile Include="ExtensibleStorage\ExtensibleStorageUtil.cs" />
+    <Compile Include="ExtensibleStorage\ICoustomStorage.cs" />
+    <Compile Include="ExtensibleStorage\ModelFileInformation.cs" />
     <Compile Include="Geometry\EdgeInfo.cs" />
     <Compile Include="Geometry\Geometry.cs" />
     <Compile Include="Information.cs" />