Як Використовувати Revit IUpdater

Інтерфейс з назвою IUpdater - це ще один метод DMU (Dynamic Model Update). Він є гнучкішим за Event Hadler, тому що у нас є більше варіантів у визначенні тригеру події. Хороша річ у тому, що ми можемо запустити IUpdater, коли зробимо будь-яку модифікацію елемента, або створивши новий елемент, або змінивши існуючу геометрію. Завантажте зразок коду з моєї сторінки GitHub сторінки.

Прочитайте попередню статтю про Event Hadler, де я пояснив, як працюють функції __selfinit__ та togglestate. План полягає в тому, щоб створити екземпляр класу IUpdater, зареєструвати та задати його тригер.

Спочатку нам потрібен весь необхідний імпорт.:

# -*- coding: UTF-8 -*-
import os
from pyrevit import framework
from pyrevit import script
from pyrevit.framework import AppDomain
import Autodesk
from Autodesk.Revit.UI import *
from Autodesk.Revit.DB import *
import System
from System import Guid

Це стандартне тіло класу  IUpdater:

class MyUpdater(IUpdater):

    def __init__(self, addinId):
        '''type UpdaterId, mix of Addin ID and updater GUID
           choose a different GUID for each updater !!! '''
        self.updaterID = UpdaterId(addinId,
            Guid("CBCBF6B2-4C06-42d4-97C1-D1B4EB593100"))

    def GetUpdaterId(self):
        return self.updaterID

    def GetUpdaterName(self):
        return 'MyUpdater'

    def GetAdditionalInformation(self):
        return 'MyUpdater (explanation, details, warnings)'

    def GetChangePriority(self):
        return ChangePriority.Structure

    def Execute(self, updaterData):
        up_doc = updaterData.GetDocument()   #document
        uidoc = __revit__.ActiveUIDocument
        #elems = updaterData.GetAddedElementIds()
        elems = updaterData.GetModifiedElementIds()
        # use a subtransaction in the current opened transaction
        if script.get_envvar(UPDATER_TEST):

            t = SubTransaction(up_doc)
            t.Start()
            try:
                if elems:
                    for h in elems:
                        id = up_doc.GetElement(h)
                        TaskDialog.Show('Element', 'Wall Changed '+str(h)+h)
                t.Commit()
            except:
                t.RollBack()

Для різних IUpdaters необхідний унікальний ID. Скомбінуйте ID активного застосунку та GUID вашого скрипту. Просто пропишіть будь-які значення:

Guid("CBCBF6B2-4C06-42d4-97C1-D1B4EB593100"))

Інші властивості необов’язкові, але необхідні для синтаксису. Нас цікавить метод Execute, де ми пишемо інструкції для Revit. Визначте документ та uidoc всередині функції Execute, інакше це призведе до помилки при запуску revit без відкритого документу.

up_doc = updaterData.GetDocument()   #document
uidoc = __revit__.ActiveUIDocument

Ви можете знайти елементи, що були створені чи модифіковані, щоб робити з ними подальші маніпуляції:

elems = updaterData.GetAddedElementIds()
or
elems = updaterData.GetModifiedElementIds()

Далі, додайте умову виконувати скрипт, якщо перемінна середовища дорівнює True(читайте Event Handler)

if script.get_envvar(UPDATER_TEST)

Нам необхідно відкрити SubTransaction, щоб внести зміни в документ, написати інструкції та закрити SubTransaction. Метод Rollback() використовується, якщо виникає помилка.

Далі, створіть об'єкт IUpdater та зареєструйте за допомогою smartbutton __selfinit__ функції. If умова необхідна, щоб запобігти багаторазовим реєстраціям:

def __selfinit__(script_cmp, ui_button_cmp, __rvt__):
    my_updater = MyUpdater(app.ActiveAddInId)
    if UpdaterRegistry.IsUpdaterRegistered(my_updater.GetUpdaterId()):
        UpdaterRegistry.UnregisterUpdater(my_updater.GetUpdaterId())
    UpdaterRegistry.RegisterUpdater(my_updater)

Та додайте тригер. Наприклад, якщо необхідно моніторити сторені елементи, використовуйте GetChangeTypeElementAddition () або GetChangeTypeGeometry (), щоб відстлідковувати модифікацію існуючих елементів. UpdateRegistry метод потребує IUpdater ID, фільтр елементів та тип тригеру:

filter = ElementCategoryFilter(BuiltInCategory.OST_Walls)
UpdaterRegistry.AddTrigger(my_updater.GetUpdaterId(), filter,
Element.GetChangeTypeGeometry())
or
UpdaterRegistry.AddTrigger(my_updater.GetUpdaterId(), filter,
Element.GetChangeTypeElementAddition())

Область застосування IUpdater величезна. В одному з моїх проектів з автоматизації рутини оформлення креслень, я використав метод GetChangeTypeElementAddition(), щоб відслідковувати створені розміри і запускати алгоритм який розсуває розміри в заданих напрямка. Наприклад:

 

 

Коментарії(3)

...
Yevgeniy1 рік, 11 місяців ago

Доброго дня! Аплодую Вашій роботі! Питання - чи можливо реалізувати IUpdater для скрипта Dynamo?

...
Yevgeniy1 рік, 11 місяців ago

Доброго дня! Аплодую Вашій роботі! Питання - чи можливо реалізувати IUpdater для скрипта Dynamo?

...
Yevgeniy1 рік, 11 місяців ago

Доброго дня! Аплодую Вашій роботі! Питання - чи можливо реалізувати IUpdater для скрипта Dynamo?