Фильтры - Скрыть все элементы, кроме элементов заданной системы

Автор Тема: Фильтры - Скрыть все элементы, кроме элементов заданной системы  (Прочитано 8449 раз)

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

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
Доброго времени суток!
Теперь у меня следующая цель - при выборе воздуховода нужно что бы оставалась видима только та система,которой принадлежит этот воздуховод(остальные бы скрывались).Вот мои успехи
Код - C# [Выбрать]
  1.         Parameter Namesystem = elem.get_Parameter(BuiltInParameter.RBS_SYSTEM_NAME_PARAM);
  2.         View view = doc.ActiveView;
  3.  
  4.         IList<ElementId> categories = new List<ElementId>();
  5.         categories.Add(new ElementId(BuiltInCategory.OST_PlaceHolderDucts));
  6.         categories.Add(new ElementId(BuiltInCategory.OST_DuctLinings));
  7.         categories.Add(new ElementId(BuiltInCategory.OST_DuctInsulations));
  8.         categories.Add(new ElementId(BuiltInCategory.OST_DuctTerminal));
  9.         categories.Add(new ElementId(BuiltInCategory.OST_MechanicalEquipment));
  10.  
  11.         IList<FilterRule> rules = new List<FilterRule>();
  12.         rules.Add(ParameterFilterRuleFactory.CreateNotContainsRule(Namesystem.Id, Namesystem.AsString(), true));
  13.  
  14.         ParameterFilterElement filter = null;
  15.         using (Transaction t = new Transaction(doc, "Create and Apply Filter"))
  16.         {
  17.             t.Start();
  18.             filter = ParameterFilterElement.Create(doc, "2222", categories, rules);
  19.             view.AddFilter(filter.Id);
  20.             t.Commit();
  21.         }
  22.         using (Transaction t = new Transaction(doc, "Set Visibility Appearance"))
  23.         {
  24.             t.Start();
  25.             view.SetFilterVisibility(filter.Id, false);
  26.             t.Commit();
  27.         }
  28.  
у меня не все элементы исчезают ,которые принадлежат другим системам. я так понимаю нужно добавить строки categories.Add(new ElementId(BuiltInCategory.OST_PlaceHolderDucts)); все что начинается на OST_Duct ?
« Последнее редактирование: 23-01-2015, 08:27:48 от Виктор Чекалин »

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
goblya,
Полезная у Вас задачка.

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

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

Но, так нельзя создать фильтр без категорий, то задача заключается в том, чтобы спрятать все элементы всех категорий, у которых параметр Имя системы не содержит заданное значение.
Таким образом, надо включить все категории в фильтр. Получить все категории, доступные для фильтра, можно с помощью метода ParameterFilterUtilities.GetAllFilterableCategories()



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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
получается нужно создать следующую конструкцию
Код - C# [Выбрать]
  1.  
  2. categoryCheckedListBox.Items.Clear();
  3. ICollection<ElementId> filterCatIds = ParameterFilterUtilities.GetAllFilterableCategories();
  4. foreach (ElementId id in filterCatIds)
  5. {
  6. categoryCheckedListBox.Items.Add(EnumParseUtility<BuiltInCategory>.Parse((BuiltInCategory)id.IntegerValue));
  7. }
  8.  
каким образом дальше добавить полученные параметры в фильтр?

--
Для выделения кода C#, используйте пожалуйста тэг code=csharp. Так читать код гораздо приятнее.
« Последнее редактирование: 23-01-2015, 11:35:51 от Виктор Чекалин »

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
goblya,
использовать для чего? У Вас здесь затесался список с чекбоксами для выделения категорий. Вы как его хотите использовать? В описаной первоначально задаче, пользователю не нужно ничего выделять..
Нужно просто взять все категории и передать их в фильтр.
в этой строке
Код - C# [Выбрать]
  1. filter = ParameterFilterElement.Create(doc, "2222", categories, rules);
третим параметром идет список категорий. Тип - ICollection<ElementId>

Метод ParameterFilterUtilities.GetAllFilterableCategories() возвращает тоже ICollection<ElementId>
Соответственно, нужно просто использовать этот список, вместо списка, сформированного вручную.
Код - C# [Выбрать]
  1. filter = ParameterFilterElement.Create(doc, "2222", ParameterFilterUtilities.GetAllFilterableCategories(), rules);

P.S.
Код - C# [Выбрать]
  1. EnumParseUtility<BuiltInCategory>.Parse((BuiltInCategory)id.IntegerValue)
что за велосипед? (BuiltInCategory)id.IntegerValue вполне достаточно.

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
что то он мне ошибку выдает в новой строчке
Код - C# [Выбрать]
  1.         View view = doc.ActiveView;
  2.         IList<FilterRule> rules = new List<FilterRule>();
  3.         rules.Add(ParameterFilterRuleFactory.CreateNotContainsRule(Namesystem.Id, Namesystem.AsString(), true));
  4.         ParameterFilterElement filter;
  5.         using (Transaction t = new Transaction(doc, "Create and Apply Filter"))
  6.         {
  7.             t.Start();
  8.             filter = ParameterFilterElement.Create(doc, "2222", ParameterFilterUtilities.GetAllFilterableCategories(), rules);
  9.             view.AddFilter(filter.Id);
  10.             t.Commit();
  11.         }
  12.         using (Transaction t = new Transaction(doc, "Set Visibility Appearance"))
  13.         {
  14.             t.Start();
  15.             view.SetFilterVisibility(filter.Id, false);
  16.             t.Commit();
  17.         }
  18.  
и мне не совсем понятно как данный метод ParameterFilterUtilities.GetAllFilterableCategories() отсеит именно то что содержит параметр BuiltInParameter.RBS_SYSTEM_NAME_PARAM
« Последнее редактирование: 23-01-2015, 13:19:39 от Виктор Чекалин »

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
goblya,
Что за ошибка? Я сам не проверял метод, это только пока в теории.

не совсем понятно как данный метод ParameterFilterUtilities.GetAllFilterableCategories() отсеит именно то что содержит параметр BuiltInParameter.RBS_SYSTEM_NAME_PARAM

Метод ParameterFilterUtilities.GetAllFilterableCategories() никак не связан с параметром BuiltInParameter.RBS_SYSTEM_NAME_PARAM. Абсолютно никак. Метод лишь возвращает список категорий, которые можно использовать в фильтре. Отсеиванием занимается фильтр.

Повторюсь, Вам нужно сооздать фильтр, результатом которого будет список элементов, у которых параметр 'Имя системы' не содержит название заданной системы. Категории элементов здесь не важны. Но так как в фильтр обязатльно передать категории, то Вы просто передаете список всех возможных категорий, который как раз и возвращает метод ParameterFilterUtilities.GetAllFilterableCategories()

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

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
выдает следующую ошибку, на всякий случай и код прикладываю

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
Становится интересней.

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

Пока все в теории, но похоже одним фильтром тут не обойтись.
1) Нужно выбрать все элементы, у которых нет параметра 'Имя системы'. Такие элементы уж точно не принадлежат ни одной системе и их, по условию задачи нужно скрыть на виде.
2) Для элементов, у которых есть свойство 'Имя системы', в значение параметра не должно содеражться название заданной системы. Это, по сути, то, что уже есть. Единственно надо как то определить правильные категории, у которых есть этот параметр.

Пока не могу сказать как.. Поищу.

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
На счет условий, 1 условие я считаю не нужным.Потому как если я работаю с планами и разрезами, то выполнение 1 условия повлечет выключения архитектуры и конструктива, тогда без архитектуры мне 1 система особо и не нужна.Если у меня 3d вид , тут возможны 2 варианта , либо у меня изометрии моих систем(при выключенной архитектуре) а значит отключать архитектуру и нет необходимости, 2 вариант это координация систем когда у меня включена инженерка и архитектура, опять же если нужно изолировать 1 систему , то просто 1 система на координации не нужна без архитектуры.
На счет фильтров, там получается что если не задавать категории или задать категорию у которой нет параметра "имя системы" (RBS_SYSTEM_NAME_PARAM) то правило обнуляется /становится пустым, т.е. нужно до создания правила обнаружить те категории у которых есть данный параметр.
На счет алгоритмов, я понимаю всю последовательность действий. если бы это был автокад и lisp то у меня бы вопросов не возникло, а вот с C# я впервые столкнулся.
« Последнее редактирование: 23-01-2015, 15:16:08 от goblya »

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
goblya, условия я не навязываю. Ведь все от задачи зависит:)
Если нужно отобразить только элементы системы без всего остального, то нужно использовать условия, как я предложил. Если нужно скрыть только MEP элементы, но оставить элементы выбранной системы, то нужно так, как вы описали. Из иходного вопроса это не сильно было понятно.

А так, значит вам нужно использовать только второе условия, которые я описал выше.

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
так я не совсем понял как осуществить 2 вариант ,если заменить на вашу строчку
filter = ParameterFilterElement.Create(doc, "2222", ParameterFilterUtilities.GetAllFilterableCategories(), rules); то revit выдает ошибку и не создает ни фильтр ни правило

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
goblya, полное решение задачи с примером и кодом описал в статье

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
awesome!
только у меня в этой части VS выдает ошибку
        try
        {
            r = uidoc.Selection.PickObject(ObjectType.Element,
                new SystemElementFilter(),
                "Выберите элемент системы");
        }
SystemElementFilter подчеркивает красным и пишет "the type of namespace name 'SystemElemtFilter' could not be found (are you missing a using directive or an assembly refererence?)"
и у меня еще один вопрос по этому поводу это Вы сделали только для 1 сисетмы. А если нужно выбрать 2 или 3 системы, а остальное отключить?В revit в ручную это сделать можно картинку прикладываю.
я так понимаю, нужно сделать множественный выбор(не более 3 элементов) и каким то образом сделать более сложное правило.

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

  • Administrator
  • *****
  • Сообщений: 692
  • Карма: 106
  • Skype: chekalin-v
только у меня в этой части VS выдает ошибку
Вы не скопировали класс SystemElementFilter из статьи.

А если нужно выбрать 2 или 3 системы, а остальное отключить?

Опять же в статье:) Есть пример, когда элемент находится в нескольких системах. В этом случае создается точно такой же фильтр, как ВЫ показали на скриншоте.
Код - C# [Выбрать]
  1. IList<FilterRule> rules = new List<FilterRule>();
  2.  
  3. var systems = systemName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  4.  
  5. foreach (var system in systems)
  6. {
  7.     rules.Add(ParameterFilterRuleFactory
  8.         .CreateNotContainsRule(new ElementId(BuiltInParameter.RBS_SYSTEM_NAME_PARAM),
  9.         system.Trim(), true));
  10. }
Т.е. просто создается несколько условий.

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

  • ADN OPEN
  • Сообщений: 13
  • Карма: 0
на счет SystemElementFilter , это слово в статье встречается только 1 раз и только в 1 строке(поиск по статье с помощью ctrl+F выдает только 1 результат)