Сообщество программистов Autodesk в СНГ

ADN Club => Revit API => Тема начата: Антон Останин от 02-06-2015, 11:47:56

Название: Выделение элемента в связанном файле
Отправлено: Антон Останин от 02-06-2015, 11:47:56
Добрый день, подскажите, пожалуйста!
Возможно ли подсветить или выделить элемент прикрепленного документа?
На входе уже имеется список элементов!
Поэтому   uidoc.Selection.PickObjects(ObjectType.LinkedElement, " ") не подойдет.
Как например это в основном документе:
uidoc.Selection.Elements.Add(elem);
Название: Re: Выделение элемента в связанном файле
Отправлено: Виктор Чекалин от 02-06-2015, 13:50:35
Антон, покопавшись в 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.         }
Идентификаторы элементов - идентификаторы из связанных файлов.
Но, к сожалению, в интерфейсе выделения так и не происходит.
Задам вопрос в техподдержку.
Название: Re: Выделение элемента в связанном файле
Отправлено: Антон Останин от 02-06-2015, 14:07:08
Виктор, благодарю!
Название: Re: Выделение элемента в связанном файле
Отправлено: Антон Останин от 02-06-2015, 15:11:25
Виктор, а таким образом можно получить выделенные элементы прикрепленного файла?

Код - C# [Выбрать]
  1.  var uiDocLinked = new UIDocument(linkedDoc);
  2. return  uiDocLinked.Selection.Elements;
  3.  
У меня ничего не возвращает, хотя элементы выделены у этого документа.
Название: Re: Выделение элемента в связанном файле
Отправлено: Виктор Чекалин от 02-06-2015, 15:17:55
У меня есть большое подозрение что либо мы получаем 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, который мы получили в коде никак не связан с тем документом, который мы видим в интерфейсе.
Обращу на это внимание при обращении в техподдержку.
Название: Re: Выделение элемента в связанном файле
Отправлено: Антон Останин от 02-06-2015, 15:22:17
Виктор Чекалин, вот именно,  у меня то же самое!
Выделяя в интерфейсе Revit, uiDocLinked.Selection возвращает неправильные значения.
Название: Re: Выделение элемента в связанном файле
Отправлено: Виктор Чекалин от 08-06-2015, 10:47:58
Антон, с техподдержкой еще общаемся. Но уже в принципе ясно, что в текущей реализации выделить элемент в связанном файле нельзя с помощью API. И на самом деле они удивились, что удалось добраться до UIDocument связанного файла.

Однако их интересует вопрос - а для чего это вообще нужно? Как в последствии будет использоваться выделенный элемент?
Название: Re: Выделение элемента в связанном файле
Отправлено: Антон Останин от 08-06-2015, 10:59:13
Виктор,  планируется что-то типа изоляции элементов, которые находятся в связанном файле.
Для этого мне и нужен список всех элементов, выделенных в модели, будь то элементы основного документа или связанных.
Название: Re: Выделение элемента в связанном файле
Отправлено: Виктор Чекалин от 08-06-2015, 11:09:37
Т.е. если я правильно понимаю, то первичной задачей является получение выделенных элементов (которые были до выполнения команды), затем, эти выделенные элементы нужно изолировать.

Изолировать элементы в связанном файле точно нельзя.
Название: Re: Выделение элемента в связанном файле
Отправлено: Антон Останин от 08-06-2015, 11:11:37
Виктор,  изолировать я их буду уже своим способом, мне необходим только список выделенных элементов.
Название: Re: Выделение элемента в связанном файле
Отправлено: SatanaXIII от 11-04-2017, 16:57:52
Тоже разбираюсь с данной задачей.
Самое интересное, что, вызвав 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 всего связанного файла, загруженного в проект.

Как выбрать несколько элементов в связанном файле непонятно.
Название: Re: Выделение элемента в связанном файле
Отправлено: Илья Дрягин от 02-07-2018, 11:20:04
Тоже разбираюсь с данной задачей.
Самое интересное, что, вызвав 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.                 }
Название: Re: Выделение элемента в связанном файле
Отправлено: ECity от 13-04-2019, 14:36:32
Извините, подниму тему немного. Второй день пытаюсь найти способ подсветить элемент.
Примерно так, как это делает форма проверки на пересечения.
Нашел только эту тему и несколько довольно заумных способов выделять элемент в основном файле.
Связанные файлы не поддаются.
Та же функция PickObjects замечательно подсвечивает.
Подскажите, плиз, куда копать?
Спасибо.
Название: Re: Выделение элемента в связанном файле
Отправлено: Александр Игнатович от 14-04-2019, 19:51:51
Ну хорошего, правильного метода, к сожалению, в 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 ждёт, когда пользователь нажмёт "Готово" или "Отмена"
Название: Re: Выделение элемента в связанном файле
Отправлено: ECity от 20-04-2019, 07:29:31
Спасибо за ответ, извините, что долго отсутствовал.

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

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

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

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



Название: Re: Выделение элемента в связанном файле
Отправлено: Александр Игнатович от 20-04-2019, 11:28:14
То есть, то выделение, которое использует тот же Pick, осуществляется внутренними средствами, но они не представлены в АПИ? Весьма странно.

Это сейчас новая функциональность покрывается API автоматически. В давние времена у Revit вообще API не было, с тех времен некоторые вещи продолжают тянуться.

Интересно, а недокументированные возможности никто не нарыл? Или приватные методы?

DotPeek в помощь, но, обычно, мало помогает, .NET-овое API - это же только обёртка вокруг приложения на C++ писанного.

Касательно задачи, наверное, есть ещё один способ, но трудоемкий и опять же с ограничениями. В 2018-ом Revit появился IDirectContext3DServer, с его помощью можно в 3D-виде дорисовать что-нибудь. См пример в DSK: Samples\DuplicateGraphics\CS
Название: Re: Выделение элемента в связанном файле
Отправлено: ECity от 20-04-2019, 11:51:17
Цитировать
Это сейчас новая функциональность покрывается API автоматически
Сорри, не понял.


Я вот тут еще про одну вещь подумал: В ручном режиме можно выделить элемент и через правую кнопсу попросить "Переопределить графику на виде", а потом "Для элемента". Там можно изменить цвет линий, элемент "выделится". А потом можно "сбросить" и он опять станет черным. Пытался найти это в АПИ, но как обычно не нашел. Оно есть и я слепошар? Или его нет? Так то почти то, что надо ведь?


P.S. А дизассемблирование помогает только тогда, когда знаешь, что искать и где. А тут... Не будешь ведь все АПИ просматривать :)
Название: Re: Выделение элемента в связанном файле
Отправлено: Александр Игнатович от 20-04-2019, 12:27:41
Сорри, не понял.

Все новые фичи, которые добавляются в каждой следующей версии, также доступны в API.

Переопределить графику на вид

Не поможет, оно в API опять же только для основного файла есть, со связанными не получится. Метод View.SetElementOverrides