настройка оффсетов для ductFitting(transition)

Автор Тема: настройка оффсетов для ductFitting(transition)  (Прочитано 8307 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Доброе время суток. при создании нового семества ductFitting(transition) предлагаются системные оффсеты "OffsetWidth" и "OffsetDepth". для моих целей нужны другие оффсеты. я могу задать зависимость моих оффсетов от этих но тогда их нельзя будет редактировать, только просматривать значения.

Вопрос в следующем - где "OffsetWidth" и "OffsetDepth" считаются и можно ли подменить их на свои?

На сколько я понял данные значения считаются автоматически рейвитом при коннекте 2-х дактов. Можно ли программно переопределить расчеты для моих фиттингов.

Могу ошибаться, буду рад любой полезной информации на этот счет.

Заранее спасибо.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
LmRArtist, добрый день.

Смещения по умолчанию создаются Revit в момент создания фитинга и зависит от размера соединяемых воздуховодов. Значение судя по всему рассчитывается таким образом, чтобы центры соединяемых воздуховодов  совпадали.
О том можно ли это поведение изменить в интерфейсе Revit, я вам не подскажу.

Программно задать нужные значение смещений можно с помощью Dynamic Model Updater после создания фитинга.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Dynamic Model Updater срабатывает уже после создания. Например при расчетах геометрии фиттинга если использовать мои оффсеты то получается ситуация - рисуем раутингом duct - transition - duct. Ревитовские оффсеты посчитались верно, но мы их в геометрии не используем, поэтому рисуется соединение со смещением, потом срабатывает Updater и считаются мои оффсеты. геометрия меняется на правильную, но излом, полученный при построении остается...

если при расчетах использовать ревитовские оффсеты, то нужно выстраивать зависимость ревитовских оффсетов от моих. следовательно при том же раутинге мои оффсеты не считаются автоматически, ревитовские мы подменяем и получается что ран опять будет построен не верно.

следовательно вопрос можно ли в Updater узнать что именно изменилось в фиттинге (какой именно параметр) без построения системы контроля изменений (ну или как её назвать правильно)...
« Последнее редактирование: 07-04-2014, 11:10:26 от Виктор Чекалин »

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Узнать что именно изменилось при помощью DMU нельзя. Можем лишь знать что объект изменился.

Пока задача не очень ясна. Можете поподробней рассказать, что за фитинг, какой результат в итоге хотите получить и почему не подходят стандартные смещения? Желательно с изображениями.

P.S. Большая просьба не писать английские слова русскими буквами, тем более что вы это делаете неправильно. Очень тяжело читать в итоге. Особенно Рейвит... Бррр... где вы такое вообще услышали..

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Прошу прощения за мой английский...)
Задача - имеется ductFitting в MEP. необходимо сделать подобный в Revit. параметры должны быть идентичными, чтобы для пользователей было всё понятно (поэтому стандартные смещения не подходят)

в частности offsetWidth - это смещение от правой грани на входе до центра на выходы.
моё смещение Left Set - это смещение от левой грани на входе до левой грани на выходе.
их зависимость - Left Set = WidthIn - 0.5 * WidthOut - offsetWidth

Вложил примерный rfa. Сделал зависимость LeftSet от OffsetWidth. всё работает замечательно, но пропадает возможность редактировать LeftSet. А это не приемлемо!

PS:
Если делать расчет геометрии через OffsetWidth:
Меняется OffsetWidth я могу  программно поменять LeftSet, для этого 2 триггера:

var ductFittingCatFilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctFitting);
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), ductFittingCatFilter, Element.GetChangeTypeElementAddition());
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), ductFittingCatFilter, Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.RBS_FAMILY_CONTENT_OFFSET_WIDTH)));

Осталось осуществить реакцию на изменение Left Set, чтобы когда пользователь менял значение Left Set изменялось и OffsetWidth, пока что непонятно как это сделать...

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Теперь стало ясно.
Вообще задача больше походит на пользовательскую, ежели на программирование и возможно решение есть.

Если же говорить о программном решение этой проблемы, то вы мыслите в верном направлении. А что мешает добавить триггер на изменение параметра Left Set?

Метод Element.GetChangeTypeParameter в качестве входного параметра может принимать также и объект типа Parameter. Правда не знаю, подействует ли триггер только на тот объект, параметры которого вы передали, либо на все объекты. Надо пробовать.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
на счет того что подействует на всё объекты это не проблема, так как можно сделать проверку...

Вы писали "Метод Element.GetChangeTypeParameter в качестве входного параметра может принимать также и объект типа Parameter."
Я не могу получить Parameter "Left Set". только BuiltInParameter. возможно я делаю это всё не в тот момент (при открытии Revit)...
Буду продолжать копать в этом направлении...

Спасибо за ответы. Если появятся идеи другого способа решения проблемы, то буду признателен.


Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Пока в голову приходит такое решение:

1) Создаете триггер на событие когда создается фитинг воздуховода
2) В обработке триггера ищете параметр Left Set
3) Если нашли - создаете еще один триггер на изменение параметра.


Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
В общем получилось. реагирует на все изменения, спасибо за советы! Но, честно говоря, мне такая подмена параметров не очень нравится...  если найду другое решение напишу...

вот кусок кода

Код - C# [Выбрать]
  1. private void documentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
  2.         {
  3.             var pd = ProjectData.Get(e.GetDocument());
  4.  
  5.             var document = e.GetDocument();
  6.             foreach (var changedElementId in e.GetAddedElementIds())
  7.                 AddTrigger(document, changedElementId);
  8.         }
  9.  
  10. private void AddTrigger(Document document, ElementId elementId)
  11.         {
  12.             var element = document.GetElement(elementId);
  13.             if (element != null && element.Name == "ХХХ")//проверку по другому можно сделать...
  14.             {
  15.                 Parameter LeftSet = element.get_Parameter("Left Set");
  16.                 if (LeftSet != null)
  17.                 {
  18.                     var ductFittingCatFilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctFitting);
  19.                     var updaterLeftSet = new TransitionLeftSetUpdater(application.ActiveAddInId);
  20.                     UpdaterRegistry.RegisterUpdater(updaterLeftSet);
  21.                     UpdaterRegistry.AddTrigger(updaterLeftSet.GetUpdaterId(), ductFittingCatFilter, Element.GetChangeTypeParameter(LeftSet));
  22.                 }
  23.  
  24.                 Parameter TopChange = element.get_Parameter("Top Change");
  25.                 if (TopChange != null)
  26.                 {
  27.                     var ductFittingCatFilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctFitting);
  28.                     var updaterTopChange = new TransitionTopChangeUpdater(application.ActiveAddInId);
  29.                     UpdaterRegistry.RegisterUpdater(updaterTopChange);
  30.                     UpdaterRegistry.AddTrigger(updaterTopChange.GetUpdaterId(), ductFittingCatFilter, Element.GetChangeTypeParameter(TopChange));
  31.                 }
  32.             }
  33.         }
« Последнее редактирование: 07-04-2014, 17:08:00 от Виктор Чекалин »

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
В данном случае использовать событие DocumentChanged не самый лучший вариант.
Событие будет срабатывать очень часто, когда вы делаете любое изменение с любыми объектами и может ощутимо замедлить работу.

Используйте также DMU. там хоть можно отфильтровать элементы по категории и только на добавление. Т.е. триггер у вас будет срабатывать только когда добавляются (и только добавляются) объекты определенной категории.

Но все же мне кажется задачу можно решить и без программирования, хотя могу и ошибаться. Попробуйте на пользовательском форуме спросить, можно ли сделать так чтоб при изменении одного параметра менялось другое и наоборот.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
пробовал в DMU вешать на UpdaterRegistry.AddTrigger(updaterOffsetWidth.GetUpdaterId(), ductFittingCatFilter, Element.GetChangeTypeElementAddition());
при срабатывании хотел добавлять новый Updater. падает на UpdaterRegistry.RegisterUpdater.    (нельзя добавлять внутри DMU)
так же нельзя добавлять новый триггер UpdaterRegistry.AddTrigger...
« Последнее редактирование: 07-04-2014, 17:55:27 от LmRArtist »

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
А Updater, в который добавляли триггер, был тот же самый, что и Updater, который сработал?

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
нет, другой.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Добрый день.

В общем у меня было опасение, что задав триггер на изменение параметра, триггер будет срабатывать только если будет изменен параметр того элемента, параметр которого вы использовали при установке триггера.

Сейчас проверил. Это не так. Триггер будет срабатывать для всех элементов, у которых есть этот параметр.

Т.е. выполнив однажды вот такой код:
Код - C# [Выбрать]
  1.             // Ищем параметр элемента
  2.             var parameter = selectedElement.get_Parameter("Left Set");
  3.            
  4.             // регистрируем Updater
  5.             Updater1 updater1 = new Updater1(commandData.Application.ActiveAddInId);
  6.             UpdaterRegistry.RegisterUpdater(updater1);
  7.  
  8.             // Добавляем триггер на изменение параметра
  9.             UpdaterRegistry.AddTrigger(updater1.GetUpdaterId(), new ElementCategoryFilter(BuiltInCategory.OST_DuctFitting), Element.GetChangeTypeParameter(parameter));
  10.  

Триггер будет срабатывать на все экземпляры заданного семейства с параметром Left Set.

Таким образом, нет необходимости задавать триггер для каждого элемента.

Но теперь возникает другая задача. В какой момент зарегистрировать триггер. Ведь нужно получить параметр. А его мы можем получить только если у нас открыт документ и в нем есть нужный фитинг.

Напрашивается конечно наличие возможности задать GUID общего параметра в методе Element.GetChangeTypeParameter(). Тогда можно было при старте приложения зарегистрировать триггер на изменение параметра с заданным Guid. Но, к сожалению, такого нет.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Добрый день. Да, вы правы, я тоже столкнулся с этим.
Пока оставил данное решение. Но наработки надеюсь пригодятся.
Сейчас копаю в сторону создания в revit собственных оффсетов - задача в том чтобы Revit считал мои оффсеты так же как считает OffsetWidth и OffsetHeight. пока ничего конкретного нет. как будет и если конечно получится поделюсь информацией.