Revit二次开发之 动态模型更新(DMU: Dynamic Model Update)功能

经常我们对一些元素进行更改后,需要出发其他元素的调整,比如我们定义一种墙体,这个墙体的门永远在墙的中心,那么当改变墙体的长度的时候,则需要自动调整门洞的位置。

我们肯定想得到,用DocumentChanged事件,一旦文档发生改变,则调用当前事件,发现墙体变化了去修改门洞,但当前方法会造成一个巨大的安全隐患,你修改墙体-DocumentChanged-修改门窗-DocumentChanged--会出现一个事件的循环调用,造成当前修改无法完成,要实现以上功能,则需要利用revit提供的机制DMU功能(Dynamic Model Update)。

DMU被称为动态模型更新,他会根据修改的模型信息,调整自己或者其他模型。

案例如下:

1、注册一个更新RegisterUpdater  

通过以下代码,可以向当前的文档中注册一个更新元素

//定义一个更新
SpatialFieldUpdater updater = new SpatialFieldUpdater(container,uiApp.ActiveAddInId);
//向文档中注册一个更新对象 if (!UpdaterRegistry.IsUpdaterRegistered(updater.GetUpdaterId())) UpdaterRegistry.RegisterUpdater(updater, doc);

2、添加一个监听AddTrigger接口

//添加要监听的对象

IList<ElementId> idCollection = new List<ElementId>();
idCollection.Add(element.Id);
UpdaterRegistry.RemoveAllTriggers(s_updaterId);

//添加一个监听行为,主要对添加的元素进行监听
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), doc, idCollection, Element.GetChangeTypeGeometry());

通过以上的监听,实现了对传入的elementId进行了监听。AddTrigger函数主要三个重载,分别是:

AddTrigger(UpdaterId, ElementFilter, ChangeType) 对过滤的对象进行监听‘

AddTrigger(UpdaterId, Document, ElementFilter, ChangeType) 对指定文档的过滤元素进行监听

AddTrigger(UpdaterId, Document, ICollection<(Of <<'(ElementId>)>>), ChangeType) 对指定文档,指定集合的元素进行监听

可以通过Element的以下方法,来获取需要监听的改变事件,如下表:

编号

方法

说明

1

GetChangeTypeAny

元素的任意改变

2

GetChangeTypeElementAddition

元素的添加

3

GetChangeTypeElementDeletion

元素的删除

4

GetChangeTypeGeometry

元素的图形的改变

5

GetChangeTypeParameter(ElementId)

指定元素的参数改变

6

GetChangeTypeParameter(Parameter)

参数的值改变

ChangeType主要是元素监听的类型,可以通过元素的各种GetChangeType类获取,以下定义,如果元素的空间字段发生改变,则实现更新

3、注册更新元素

主要用于对以上监听的对象,图形发生变化的时候,需要做的处理,如下

public class SpatialFieldUpdater : IUpdater
  {
            public string GetAdditionalInformation() { return "AVF DMU Thread sample"; }
            public ChangePriority GetChangePriority() { return ChangePriority.FloorsRoofsStructuralWalls; }
            public UpdaterId GetUpdaterId() { return s_updaterId; }
            public string GetUpdaterName() { return "AVF DMU Thread"; }
    
public SpatialFieldUpdater(MultithreadedCalculationContainer _container, AddInId addinId)
            {
                containerOld = _container;
                s_updaterId = new UpdaterId(addinId, new Guid("FBF2F6B2-4C06-42d4-97C1-D1B4EB593EFF"));
            }

      
            public void Execute(UpdaterData data)
            {

                UIApplication uiApp = new UIApplication(data.GetDocument().Application);
                uiApp.Idling -= containerOld.UpdateWhileIdling;
                containerOld.Stop();

         
                Document doc = data.GetDocument();
                View activeView = doc.GetElement(s_activeViewId) as View;
                SpatialFieldManager sfm = SpatialFieldManager.GetSpatialFieldManager(activeView);
                sfm.Clear();

            }

 }
原文地址:https://www.cnblogs.com/minhost/p/14258737.html