Выделение элемента в связанном файле

Автор Тема: Выделение элемента в связанном файле  (Прочитано 9779 раз)

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

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

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Добрый день, подскажите, пожалуйста!
Возможно ли подсветить или выделить элемент прикрепленного документа?
На входе уже имеется список элементов!
Поэтому   uidoc.Selection.PickObjects(ObjectType.LinkedElement, " ") не подойдет.
Как например это в основном документе:
uidoc.Selection.Elements.Add(elem);
« Последнее редактирование: 02-06-2015, 13:12:10 от Виктор Чекалин »

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Антон, покопавшись в API, нашел, что это вроде бы сделать можно.
Свойство Selection есть у класса UIDocument. Получить UIDocument мы можем только текущий с помощью свойства UIApplication.ActiveUIDocument. Так как элемент находится в связанном файле, то этот способ не подходит.

Но объект класса UIDocument можно создать, передав в параметр конструктора Document, а его то мы получить можем.

В итоге получился вот такой код:
Код - C# [Выбрать]
  1.         public void SelectElementInLinkedFile()
  2.         {
  3.                 var doc = ActiveUIDocument.Document;
  4.                
  5.                 // Выделение в текущем докменте работает
  6.                 //ActiveUIDocument.Selection.SetElementIds(new ElementId[] {new ElementId(304708)});
  7.                
  8.                 // получаем связанные документы
  9.                 var linkedDocs = GetLinkedDocuments(doc);
  10.                
  11.                 // берем первый связанный документ
  12.                 var firstLinkedDoc = linkedDocs.FirstOrDefault();
  13.                
  14.                 // создаем UIDocument
  15.                 var uiDocLinked = new UIDocument(firstLinkedDoc);
  16.                
  17.                 // выделяем элемент в связанном файле
  18.                 uiDocLinked.Selection.SetElementIds(new List<ElementId> {new ElementId(578591), new ElementId(577609) });
  19.                
  20.         }
Идентификаторы элементов - идентификаторы из связанных файлов.
Но, к сожалению, в интерфейсе выделения так и не происходит.
Задам вопрос в техподдержку.

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

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Виктор, благодарю!

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

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Виктор, а таким образом можно получить выделенные элементы прикрепленного файла?

Код - C# [Выбрать]
  1.  var uiDocLinked = new UIDocument(linkedDoc);
  2. return  uiDocLinked.Selection.Elements;
  3.  
У меня ничего не возвращает, хотя элементы выделены у этого документа.
« Последнее редактирование: 02-06-2015, 15:12:53 от Виктор Чекалин »

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
У меня есть большое подозрение что либо мы получаем UIDocument связанного файла не так (хотя я не вижу других способов его получить), либо в реализации API в части данной функциональности есть недоработки.

Обнаружил следующую интересную особенность. Первоначально количество выделенных элементов у связанного файла, которое я получил через uiDocLinked.Selection.Elements.Size равно 1. Хотя ничего не выделено. Затем, в качестве эксперимента, я выделил попробовал выделить объекты с помощью кода uiDocLinked.Selection.SetElementIds(new List<ElementId> {new ElementId(578591), new ElementId(577609) });. uiDocLinked.Selection.Elements.Size стал равен 2. Что логично.
После этого я в интерфейсе выделил 4 объекта из связанного файла и заново запустил команду. uiDocLinked.Selection.Elements.Size так и остался равен 2.

То есть тот UIDocument, который мы получили в коде никак не связан с тем документом, который мы видим в интерфейсе.
Обращу на это внимание при обращении в техподдержку.

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

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Виктор Чекалин, вот именно,  у меня то же самое!
Выделяя в интерфейсе Revit, uiDocLinked.Selection возвращает неправильные значения.

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Антон, с техподдержкой еще общаемся. Но уже в принципе ясно, что в текущей реализации выделить элемент в связанном файле нельзя с помощью API. И на самом деле они удивились, что удалось добраться до UIDocument связанного файла.

Однако их интересует вопрос - а для чего это вообще нужно? Как в последствии будет использоваться выделенный элемент?

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

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

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

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

Изолировать элементы в связанном файле точно нельзя.

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

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Виктор,  изолировать я их буду уже своим способом, мне необходим только список выделенных элементов.

Оффлайн SatanaXIII

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
Тоже разбираюсь с данной задачей.
Самое интересное, что, вызвав PickObject от текущего документа с параметром ObjectType.LinkedElement, можно получить ожидаемое поведение по предоставлению выбора любого элемента из загруженного связанного файла. Но как только любой элемент выбирается, любой повторный вызов PickObject завершается выбросом исключения OperationCanceledException, так и не начавшись. При чем вызов функции множественного выбора объектов PickObjects завершается исключением сразу. Как и ровно так же бросаются исключениями попытки вызвать PickObject или PickObjects от документа из связанного файла.

Я изобрел такой велосипед:
Код - C# [Выбрать]
  1. public void SelectElementsInLinkedDoc(Autodesk.Revit.DB.Document CurrDoc)
  2. {
  3.     UIDocument CurrUIDoc = new UIDocument(CurrDoc);
  4.     Selection CurrDocSelection = CurrUIDoc.Selection;
  5.            
  6.     var linkedDocs = GetLinkedDocuments(CurrDoc);
  7.     var firstLinkedDoc = linkedDocs.FirstOrDefault();
  8.     var LinkedUIDoc = new UIDocument(firstLinkedDoc);
  9.     Selection LinkedDocSelection = LinkedUIDoc.Selection;
  10.  
  11.     List<ElementId> RefElementIdLinkedElementsList = new List<ElementId>();
  12.     bool Halt = false;
  13.     while (!Halt)
  14.     {
  15.         try
  16.         {
  17.             Reference CurrRef = CurrDocSelection.PickObject(ObjectType.LinkedElement, "Select element in a linked document");
  18.             if (CurrRef != null)
  19.                 RefElementIdLinkedElementsList.Add(LinkedUIDoc.Document.GetElement(CurrRef).Id);
  20.  
  21.             LinkedDocSelection.SetElementIds(RefElementIdLinkedElementsList);
  22.         }
  23.         catch (Autodesk.Revit.Exceptions.OperationCanceledException UserCancelEx)
  24.         {
  25.             Halt = true;
  26.         }
  27.     }
  28. }
Но к сожалению он тоже не работает. С помощью него находится только ElementId всего связанного файла, загруженного в проект.

Как выбрать несколько элементов в связанном файле непонятно.
Бензопила пилит тело, а виолончель душу.

Оффлайн Илья Дрягин

  • ADN OPEN
  • Сообщений: 25
  • Карма: 2
  • Стройтэкпроект
Тоже разбираюсь с данной задачей.
Самое интересное, что, вызвав PickObject от текущего документа с параметром ObjectType.LinkedElement, можно получить ожидаемое поведение по предоставлению выбора любого элемента из загруженного связанного файла. Но как только любой элемент выбирается, любой повторный вызов PickObject завершается выбросом исключения OperationCanceledException, так и не начавшись. При чем вызов функции множественного выбора объектов PickObjects завершается исключением сразу. Как и ровно так же бросаются исключениями попытки вызвать PickObject или PickObjects от документа из связанного файла.

Но к сожалению он тоже не работает. С помощью него находится только ElementId всего связанного файла, загруженного в проект.

Как выбрать несколько элементов в связанном файле непонятно.

у меня помещения из связанного файла выбираются вот так:
Код - C# [Выбрать]
  1.                 IList<Reference> linkelements = selection.PickObjects(ObjectType.LinkedElement, "Выберите помещения в связаном файле");
  2.                 foreach (Reference lelement in linkelements)
  3.                 {
  4.                     RevitLinkInstance rlinkinst = doc.GetElement(lelement.ElementId) as RevitLinkInstance;
  5.                     Autodesk.Revit.DB.Document linkedDoc = rlinkinst.GetLinkDocument();
  6.                     Element relem = linkedDoc.GetElement(lelement.LinkedElementId);
  7.                     selectedrooms.Add(relem);
  8.                 }

Оффлайн ECity

  • ADN OPEN
  • Сообщений: 12
  • Карма: 0
Извините, подниму тему немного. Второй день пытаюсь найти способ подсветить элемент.
Примерно так, как это делает форма проверки на пересечения.
Нашел только эту тему и несколько довольно заумных способов выделять элемент в основном файле.
Связанные файлы не поддаются.
Та же функция PickObjects замечательно подсвечивает.
Подскажите, плиз, куда копать?
Спасибо.

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

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

Код - C# [Выбрать]
  1. public IList<Reference> PickObjects(
  2.         ObjectType objectType,
  3.         ISelectionFilter selectionFilter,
  4.         string statusPrompt,
  5.         IList<Reference> pPreSelected
  6. )

Последним его аргументом указывается список предварительно выбранных reference-ов. К сожалению, опять же, всё не так просто, эти Reference-ы нужно правильно приготовить.

Допустим, Вы нашли element в СВЯЗАННОМ файле. Тогда сначала получаем:
Код - C# [Выбрать]
  1. var reference = new Reference(element);
  2.  
  3. var stableRepresentation = reference.CreateLinkReference(linkedInstance).ConvertToStableRepresentation(doc); // здесь doc - ОСНОВНОЙ документ

У Вас тогда в stableRepresentation будет строка вида:
Цитировать
1a5ab77d-1ae2-4e82-872d-63be5c36dec1-00039e53:RVTLINK/1a5ab77d-1ae2-4e82-872d-63be5c36dec1-00039e52:1224485

Её нужно слегка поправить до вида:
Цитировать
1a5ab77d-1ae2-4e82-872d-63be5c36dec1-00039e53:0:RVTLINK/1a5ab77d-1ae2-4e82-872d-63be5c36dec1-00039e52:1224485

потом получаем уже непосредственно Reference методом:
Код - C# [Выбрать]
  1. var reference = Reference.ParseFromStableRepresentation(doc, fixedStableRepresentation);

Вот его уже можно добавлять в список pPreSelected, который скармливается методу Selection.PickObjects.

ISelectionFilter (3 параметр) можно создать простейший:

Код - C# [Выбрать]
  1. public class NoSelectionFilter : ISelectionFilter
  2. {
  3.         public bool AllowElement(Element elem)
  4.         {
  5.                 return false;
  6.         }
  7.  
  8.         public bool AllowReference(Reference reference, XYZ position)
  9.         {
  10.                 return false;
  11.         }
  12. }

Теперь, соответственно, всё готово, можно вызывать:
Код - C# [Выбрать]
  1. uidoc
  2.                 .Selection
  3.                 .PickObjects(ObjectType.LinkedElement, new NoSelectionFilter(), "select", references);

Не забудьте только в try-catch(OperationCanceledException) обернуть.

Недостатки метода понятны, можно убрать часть выделенного + по сути диалог получается, Revit ждёт, когда пользователь нажмёт "Готово" или "Отмена"

Оффлайн ECity

  • ADN OPEN
  • Сообщений: 12
  • Карма: 0
Спасибо за ответ, извините, что долго отсутствовал.

Ну хорошего, правильного метода, к сожалению, в API так и не появилось.

То есть, то выделение, которое использует тот же Pick, осуществляется внутренними средствами, но они не представлены в АПИ? Весьма странно.

К сожалению, описанный вами метод мне не подойдет из-за его диалоговости (тем не менее, кое-что из вами рассказанного заботливо сложил в копилочку :) ). Мне надо именно так, как делает средство поиска пересечений. Пользователь ткнул в одну строчку списка - подсветился один элемент, ткнул в другую - другой.
К счастью, это все только удобства, можно обойтись.
Но все равно жаль.

Интересно, а недокументированные возможности никто не нарыл? Или приватные методы? Ведь можно через заднее крыльцо попробовать? Знать бы еще, где оно... :)