Удаление видов не находящихся на листах

Автор Тема: Удаление видов не находящихся на листах  (Прочитано 5281 раз)

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

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

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Добрый день.
Пытаюсь удалить все виды и спецификации, которые не находятся на выделенных листах.
Делаю следующим образом
Код - C# [Выбрать]
  1.                         UIDocument uidoc = this.ActiveUIDocument;
  2.                         Document doc = uidoc.Document;
  3.                         ICollection<ElementId> selView = uidoc.Selection.GetElementIds();
  4.                         ICollection<ElementId> elemOnSelView = new List<ElementId>();
  5.                         foreach (var el in selView)
  6.                         {
  7.                                 ViewSheet sheet = doc.GetElement(el) as ViewSheet;
  8.                                 foreach(var t in SearchAndPlaceSchedule(doc, sheet))
  9.                                 {
  10.                                         elemOnSelView.Add(t);
  11.                                 }
  12.                         }
  13.                        
  14.                         ElementClassFilter fil1 = new ElementClassFilter(typeof(View));
  15.                         ElementClassFilter fil2 = new ElementClassFilter(typeof(ScheduleSheetInstance));
  16.                         LogicalOrFilter fil3 = new LogicalOrFilter(fil1, fil2);
  17.                         IEnumerable<ElementId> elements = new FilteredElementCollector(doc).WherePasses(fil3).Select(s=>s.Id as ElementId);
  18.                        
  19.                         var elemOnSelViewDistinct = elemOnSelView.Distinct();
  20.                         HashSet<ElementId> hsId = new HashSet<ElementId>(elemOnSelViewDistinct.Select(s=>s));
  21.                         var res = elements.Where(m=> !hsId.Contains(m));
  22.                        
  23.                         using (Transaction tr = new Transaction(doc))
  24.                         {
  25.                                 tr.Start("d");
  26.                                 foreach (var e1 in res)
  27.                                 {
  28.                                         try
  29.                                         {
  30.                                                 doc.Delete(e1);
  31.                                         }
  32.                                         catch {}
  33.                                 }
  34.                                 tr.Commit();
  35.                         }
  36.  

Метод для поиска видов и спек на листе
Код - C# [Выбрать]
  1.                 private List<ElementId> SearchAndPlaceSchedule(Document doc, ViewSheet sheet)
  2.                 {
  3.                         List<ElementId> shId = new List<ElementId>();
  4.                         Document scheDoc = sheet.Document;
  5.                         IEnumerable<ScheduleSheetInstance> col = new FilteredElementCollector(scheDoc, sheet.Id)
  6.                                 .OfClass(typeof(ScheduleSheetInstance))
  7.                                 .ToElements().OfType<ScheduleSheetInstance>();
  8.                         ICollection<ElementId> viewportId = sheet.GetAllViewports();
  9.  
  10.                         foreach (ScheduleSheetInstance schedInst in col)
  11.                         {
  12.                                 ElementId schedId = schedInst.ScheduleId;
  13.                                 shId.Add(schedId);
  14.                         }
  15.                        
  16.                         foreach (ElementId elId in viewportId)
  17.                         {
  18.                                 Viewport viewport = doc.GetElement(elId) as Viewport;
  19.                                 ElementId viewId = viewport.ViewId;
  20.                                 View view = doc.GetElement(viewId) as View;
  21.                                 shId.Add(view.Id);
  22.                         }
  23.                        
  24.                         return shId;
  25.                 }
  26.  
  27.  

Но он не работает и выдает следующую ошибку
Цитировать
the iterator cannot proceed due to changes made to the Element table in Revits database(typically, this can be result of an element deletion)
Никак не могу понять в чем ошибка.
Заранее спасибо за помощь!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Но он не работает и выдает следующую ошибку
Цитировать

    the iterator cannot proceed due to changes made to the Element table in Revits database(typically, this can be result of an element deletion)

Никак не могу понять в чем ошибка.
Ошибка в том, что ты удаляешь элемент в цикле, организованном итератором. И соответственно итератор дальше не может работать.
В этой статье есть более подробная информация: http://adn-cis.org/udalenie-neispolzuemyix-opornyix-ploskostej.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Спасибо, вроде исправил)

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Кстати, задачу можно решить проще.

Создать ElementParameterFilter на основе правила:
Код - C# [Выбрать]
  1. var rule = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId(BuiltInParameter.VIEWPORT_SHEET_NUMBER), "", false);

Скомбинировать его с ElementMulticlassFilter, которому передать массив typeof(View3D), typeof(ViewDrafting), typeof(ViewPlan), typeof(ViewSection)

Тогда у Вас весь поиск неразмещенных видов уместится строчек в 5 кода

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

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Спасибо за идею, сейчас попробую

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
В RevitPythonShell, на C# будет сильно лаконичнее:
Код - C# [Выбрать]
  1. from System import *
  2. from System.Collections.Generic import *
  3.  
  4. rule = ParameterFilterRuleFactory.CreateEqualsRule(ElementId(BuiltInParameter.VIEWPORT_SHEET_NUMBER), "", False)
  5.  
  6. sheetNumberFilter = ElementParameterFilter(rule)
  7.  
  8. viewTypes = List[Type]()
  9. viewTypes.Add(View3D)
  10. viewTypes.Add(ViewDrafting)
  11. viewTypes.Add(ViewPlan)
  12. viewTypes.Add(ViewSection)
  13.  
  14. vs = FilteredElementCollector(doc).WherePasses(ElementMulticlassFilter(viewTypes)).WherePasses(sheetNumberFilter).ToElements()
  15.  
  16. lookup(vs)