Отследить изменение расположения через параметр

Автор Тема: Отследить изменение расположения через параметр  (Прочитано 5070 раз)

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

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Возможно ли отследить изменения расположения (в updater-е) FamilyInstance (т.е. изменение координат X,Y,Z) через какой-то параметр (возможно есть какие то встроенные параметры семейства, отображающие эти значения) ? По вертикали Z можно отследить через параметр "Смещение", но по X,Y не нашел параметров в семействе отвечающих за это. 

Мне нужно использовать его в триггере

Код - C# [Выбрать]
  1. UpdaterRegistry.AddTrigger(updater_.GetUpdaterId(), Filter, Element.GetChangeTypeParameter(   [здесь параметр X,Y,Z]  ));

Код - C# [Выбрать]
  1. Element.GetChangeTypeGeometry
  - не отслеживает изменения расположения

Код - C# [Выбрать]
  1. Element.GetChangeTypeAny
  - отслеживает все изменения, но мне нужно только отследить изменение расположения экземпляра семейства

Сейчас не могу ничего придумать лучше, чем создать новый параметр и записывать туда значения через определение  Location.X , Location.Y, Location.Z . Поэтому и возник вопрос, возможно есть способ лучше?





Отмечено как Решение enot 14-09-2018, 10:48:46

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Из SDK про Element.GetChangeTypeGeometry:

Цитировать
Only physical changes to shape of the element(s) will trigger the updater. For example, changes like cutting a hole in a wall or adjusting its height are considered to be geometric changes. However, moving a wall to a different location without modifying its shape is not considered to be a change in geometry and will not trigger the Updater.

Так что да, только Element.GetChangeTypeAny. Попробуйте подобрать более точный фильтр, чтобы работало быстрее.

Касательно сохранения положения в пространстве X, Y, Z можете еще посмотреть в сторону ExtensibleStorage

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Вас понял. Спасибо
Цитировать
ExtensibleStorage
Можно в двух словах что это

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Внутреннее типизированное хранилище данных, которое можно назначить почти любому элементу из модели.

У Джереми Тэммика раздел в блоге: http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.23

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Касательно сохранения положения в пространстве X, Y, Z можете еще посмотреть в сторону ExtensibleStorage

Если записываю значения XYZ в ExtensibleStorage

 
Код - C# [Выбрать]
  1. public void StoreData(FamilyInstance fam_inst, XYZ dataToStore)
  2.         {
  3.             ...
  4.            
  5.             SchemaBuilder schemaBuilder = new SchemaBuilder(new Guid("XXX"));
  6.             ...
  7.  
  8.             FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField("Location", typeof(XYZ));
  9.             ...
  10.  
  11.             fam_inst.SetEntity(entity);
  12.             ...
  13.         }
  14.  

То эти значения будут хранится в ExtensibleStorage , однако мне нужен параметр ... чтобы я мог указать его ElementId в Element.GetChangeTypeParameter()


« Последнее редактирование: 14-09-2018, 19:05:51 от Александр Ривилис »

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Ну во-первых, сначала нужно попробовать получить существующую схему: Schema.Lookup, и только если она null, собирать её SchemaBuilder, во-вторых откуда у Вас появился Element.GetChangeTypeParameter, когда в начале темы Вы хотели отслеживать изменение положения элемента?

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
изменение положения объекта - это изменение значений параметра , отображающего координаты X,Y,Z элемента.   А так как в Ревит нет у FamilyInstance таковых , то думаю создать такой параметр (и динамически вписывать туда значения, если элемент перетащили). но ищу вариант лучше. может не используя значения параметра

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Сейчас поясню подробнее
Возьмем некое семейство (вернее категорию) для него создадим общий параметр "parameter_X"

ШАГ 1
отследив все изменения (а туда и попадает изменение положения) через
Код - C# [Выбрать]
  1. Element.GetChangeTypeAny
запишем     
FamilyInstance.LookupParameter( parameter_X  ) .Set (   FamilyInstance.Location.X)

ШАГ 2

Теперь у нас есть динамическая запись координаты в parameter_X  , которую мы уже можем отследить в :

Код - C# [Выбрать]
  1. Element.GetChangeTypeParameter(  [ parameter_X .Id ]  ));



Далее ...
исходя из
"Касательно сохранения положения в пространстве X, Y, Z можете еще посмотреть в сторону ExtensibleStorage"

я и пришел к мысли, может и неверной, что все вышеизложенное можно провернуть через ExtensibleStorage , а именно - создав некий параметр (а тут видимо не получится в ExtensibleStorage ) и записав туда значение координаты Х, какой плюс - этот параметр будет не редактируемым (и вообще не видимым), но привязанным к конкретной категории.

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




Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Вы мне мозг разрываете. На шаге 1 Вы уже отследили изменения.

Краткий алгоритм, который нужно реализовать в методе Execute: Для каждого измененного элемента:
1) Получаете Entity по Вашей схеме.
Если его нет то:
2а) создаем его и записываем в него текущее положение
Если есть, то:
2б) сравниваем значение из Entity с положением семейства, если не совпадает, пишем обновленное значение в Entity, делаем еще что-то полезное, для чего вы хотите отслеживать положение.

Ну еще бы хорошо отрабатывать добавление элементов, где просто записываем в storage значение положения.

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
да , на 1 шаге. отследил все в то числе и изменение положения объекта.

В чем проблема.
у меня при выполнении

Код - C# [Выбрать]
  1.     public class Updater_ : IUpdater
  2.     {
  3.         public void Execute(UpdaterData data)
  4.         {

тут происходит изменение геометрии объекта и мне подозревается что влечет за собой повторное срабатывание IUpdater-а (снова возращение к методу Element.GetChangeTypeAny)  , то есть происходит что то вроде зацикливания с последующей ошибкой .... Поэтому весь поток изменений я бы хотел ограничить только определением изменения расположения объекта, в таком случае ошибки не будет.

Насчет ExtensibleStorage и Entity  - предмет дальнейшего изучения)

Спасибо за поддержку)

 

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Ну тут всё просто. У Вас должно быть понимание, какой должен быть результат операции изменения, которое вносится в модель в IUpdater.Execute. Перед внесением изменения анализируем текущее состояние объекта, если оно = ожидаемому, то просто не трогаем его, т.е., грубо говоря, если есть Entity с сохраненным положением семейства и это значение в нем равно положению семейства, то ничего не делаем с этим элементом. А Revit, кстати, отслеживает такие моменты и прибивает апдейтеры, которые по многу раз пытаются внести изменения в 1 элемент, за что ему спасибо)

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
А Revit, кстати, отслеживает такие моменты и прибивает апдейтеры, которые по многу раз пытаются внести изменения в 1 элемент, за что ему спасибо)

Есть ли возможность самому отследить , что один и тот же апдейтер запускается повторно (2 раза подряд), и как то обработать это исключение, чтобы не было ошибки с сообщением в Ревит

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Специальных механизмов нет, но Вы можете разработать его самостоятельно, только не забудьте, что пользователь может работать с несколькими документами

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Про запуск второй раз подряд выяснилось что повторный запуск апдейтера в моем случае возникает из-за ошибки в самом методе Execute

Оффлайн enotАвтор темы

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Специальных механизмов нет, но Вы можете разработать его самостоятельно, только не забудьте, что пользователь может работать с несколькими документами
Как вы это учитываете?