Revit二次开发 - 动态模型更新DMU

当你关心的构件(注册时)行为发生改变时(它甚至可以只针对某个参数进行监听),revit会通过回调的方式相应该事件。

你的应用场景可能有:

1、用户插入门时,自动调整门距墙的距离;

2、实时统计项目中门窗的个数;

3、删除某构件时,同时自动删除它的附属构件等等操作。

class UpdaterTemplateService : IUpdater
    {
        const string UpdaterId = "082604f4-9551-4bd3-b676-d5e10fb99577";
        readonly AddInId _appId = null;
        readonly UpdaterId _updaterId = null;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="addInGuid">addin文件的ID</param>
        UpdaterTemplateService(Guid addInGuid)
        {
            System.Diagnostics.Debug.Assert(addInGuid != null && addInGuid != Guid.Empty);

            _appId = new AddInId(addInGuid);
            _updaterId = new UpdaterId(_appId, new Guid(UpdaterId));
        }

        #region IUpdater

        public void Execute(UpdaterData data)
        {
            try
            {
                var document = data.GetDocument();

                //TODO....
                //只能写子事务
            }
            catch (Exception ex)
            {
                App.Instance.Loger.Error(ex);

                System.Windows.MessageBox.Show(
                    ex.Message,
                    "错误消息",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
            }
        }

        public string GetAdditionalInformation()
        {
            return "DMU的描述,附加信息";
        }

        public ChangePriority GetChangePriority()
        {
            return ChangePriority.Views;
        }

        public UpdaterId GetUpdaterId()
        {
            return _updaterId;
        }

        public string GetUpdaterName()
        {
            return "DMU名称";
        }

        #endregion

        public static void RegisterUpdater(Guid addInGuid)
        {
            var updateSrv = new UpdaterTemplateService(addInGuid);
            var updateId = updateSrv.GetUpdaterId();

            if (!UpdaterRegistry.IsUpdaterRegistered(updateId))
            {
                UpdaterRegistry.RegisterUpdater(updateSrv, false);

                var filter = new ElementClassFilter(typeof(FamilyInstance));

                /*
                 * 对FamilyInstance元素的增加和删除监听
                 * 
                 * 如果需要关注某些有自己程序创建出来的Element,可以把每个Element附上扩展数据
                 * 然后使用ExtensibleStorageFilter过滤器注册DMU即可
                 * 
                 * DUM对用户的Ctrl + Z 无效, 可以在DocumentChanged事件中完善该机制
                 */
                UpdaterRegistry.AddTrigger(
                    updateId,
                    filter,
                    Element.GetChangeTypeElementAddition());

                UpdaterRegistry.AddTrigger(
                    updateId,
                    filter,
                    Element.GetChangeTypeElementDeletion());
            }
        }
    }

UpdaterId需要任意唯一的ID
public static void RegisterUpdater(Guid addInGuid)注册接口需要的ID为当前插件的Addin,可在OnStartup接口中获取,如下:

var addinId = application.ActiveAddInId.GetGUID();

上面代码关心FamilyInstance类别元素的增和删的操作;

revit提供了很多过滤器,仔细研究,其实它分得很细,大部分情况下能恰到好处的过滤出你关心的模型内容。


如代码注释中的描述,扩展说说DocumentChanged事件,其实在该事件中能实现撤销的操作。

比如说禁止Ctrl+V的元素拷贝,直接在该事件中给revi窗口发送Ctrl + Z的消息即可,这路子是野了点,不过效果还是不错的。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页