Revit二开—Schemachema扩展数据

  • 2020 年 8 月 10 日
  • 筆記

一.什么是Schema

       Schema是Revit扩展数据的技术关键词,revit到这里,需要对Revit二开基础有一定了解。

二.Schema架构

       建立revit扩展数据第一步是建立Schema(类似建立架构设计,设计Schema存储结构,类似设计DB 数据表结构),第二步是将扩展数据放入Entity,最终保存的位置在Element。

           

 

.代码

         SchemaMaager          

public class SchemaManager
    {
        private static SchemaManager instance;
        public static SchemaManager Current
        {
            get 
            { 
                if(instance == null)
                    instance = new SchemaManager();
                return instance;
            }
        }

        protected SchemaManager() { }


        public Schema CreateSchema(Guid id,string name,string documentation,AccessLevel readAccessLevel,AccessLevel writeAccessLevel,
            string[] fieldNames,string vendorID = "ADSK")
        {
            if (GetSchema(id) != null)
                return GetSchema(id);

            SchemaBuilder schemaBuilder = new SchemaBuilder(id);
            schemaBuilder.SetSchemaName(name);
            schemaBuilder.SetDocumentation(documentation);
            schemaBuilder.SetReadAccessLevel(readAccessLevel);
            schemaBuilder.SetWriteAccessLevel(writeAccessLevel);
            schemaBuilder.SetVendorId(vendorID);
            foreach(var fieldName in fieldNames)
            {
                schemaBuilder.AddSimpleField(fieldName, typeof(string));
            }
            return schemaBuilder.Finish();
        }

        
        public Schema GetSchema(Guid id)
        {
            return Schema.Lookup(id);
        }


        public void SetEntity<T>(Element element,Guid schemaId,string fieldName,T data)
        {
            Entity ent = element.GetEntity(GetSchema(schemaId));

            if (ent.Schema == null)
                ent = new Entity(schemaId);
            ent.Set(fieldName, JsonConvert.SerializeObject(data));
            element.SetEntity(ent);
        }

        public void SetEntity(Element element, Guid schemaId, string fieldName, string data)
        {
            Entity ent = element.GetEntity(GetSchema(schemaId));

            if (ent.Schema == null)
                ent = new Entity(schemaId);
            ent.Set(fieldName, data);
            element.SetEntity(ent);
        }


    }

View Code

         SchemaCreater

  public class SchemaCreater
    {
        public static void CreateSchemaOfID()
        {
            SchemaManager.Current.CreateSchema(SchemaIds.IDData, "Schema_ID", "Schema id data", 
                Autodesk.Revit.DB.ExtensibleStorage.AccessLevel.Public,
                Autodesk.Revit.DB.ExtensibleStorage.AccessLevel.Vendor, 
                new string[] {SchemaFields.JackExt });
        }
    }

View Code

        测试代码:              

  //扩展数据测试
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    public class SchemaDataTest : IExternalCommand
    {
       
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Document doc = commandData.Application.ActiveUIDocument.Document;
            SchemaData.SchemaCreater.CreateSchemaOfID();    //创建Schema

            Wall wall = WallHelper.CreateWall(commandData);
            UIDocument uiDocument = commandData.Application.ActiveUIDocument;

            if (wall != null)
            {
                using (Transaction trans = new Transaction(doc))
                {
                    trans.Start("jack");
                    SchemaData.SchemaManager.Current.SetEntity(wall, SchemaIds.IDData, SchemaFields.JackExt, "jack_e920572f-ba66-4af8-99d6-498d97fe0bfe");
                    trans.Commit();
                }

                return Result.Succeeded;
            }
            else
                return Result.Failed;
        }
    }

View Code

         代码架构:

               

 

    源代码下载:

            //files.cnblogs.com/files/xiaowangzi1987/RevitTestPro.rar

.注意 

          1.创建Schema不需要开启事务

                     

         2.当writeAccessLevel或readAccessLevel为Vendor的时候,vendorId必须与Addin文件中的VendorId保持一致, 否则会没有写(读)扩展数据的权限,并抛出异常;

          3.一个Entity可以有多个Schema,一个Schema可以有多个 Field 。

                如果有一个实体类需要存为扩展数据,方法一:建立一个Field,将实体类JSON序列化,存储字符串。 方法二:建立多个Field,一个Field对应实体类的属性字段。 方法三:建立多个Schema,一个Schema建一个Field,一个Field对应实体类的属性字段。