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();

            }

 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM