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

ADN Club => Revit API => Тема начата: sniip от 07-02-2016, 15:08:07

Название: Копирование спецификации или вида из пространства листа.
Отправлено: sniip от 07-02-2016, 15:08:07
Здравствуйте, пытаюсь решить следующую задачу. Есть вид и спецификация вынесенная на лист. Хочу написать макрос по которому у пользователя спрашивается вид или спецификация. Далее вид копируется с детализацией (или копируется спецификация) и у пользователя спрашивается точка. Новый вид/ спецификация вставляется в нужную точку на листе...

как вариант полное копирование листа, но все элементы что бы становились новыми т.е. скопированные.
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Виктор Чекалин от 08-02-2016, 11:30:50
sniip, день добрый.

В Revit API есть метод по копированию вида - View.Duplicate. Он делает то же самое, что и в пользовательском интерфейсе команда Дублировать. Однако, эта команда не доступна для листов. В таком случае, придется реализовывать функцию копирования самому.
Первое что приходит в голову, создать новый лист, найти все спецификации на исходном листе и с помощью ElementTransformUtils.CopyElement вставить скопировать спецификации на новый лист.
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: sniip от 08-02-2016, 15:33:03
А как разместить вид созданный на листе?
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Виктор Чекалин от 08-02-2016, 15:51:44
А как разместить вид созданный на листе?
С помощью статического метода Viewport.Create()
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: sniip от 08-02-2016, 18:57:58
Я совершенно запутался)) нужна помощь (сразу скажу что это моя первая программ в ревите, сильно не ругайте)
попробую структурировать все вопросы:
1) Мне нужно задать пользователю вопрос: выберите вид (если он на листе то он типа VIewport как я понял)
пробую таким образом:
Код - C# [Выбрать]
  1. GetElement(uiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Face,"выберите вид"))
   а) можно ли таким образом вести диалог с пользоваетелм?
   б) как тип Element преобразовать в тип VIewport?

2)  по Viewport у ищу связанный с ним вид:
Код - C# [Выбрать]
  1. View myview;
  2. myview = doc.GetElement(Viewport1.ViewId);
программа не запустилась но я думаю это единственная чать которая у меня получилась:)

3) копирую с детализацией вид :
myview.Duplicate(ViewDuplicateOption.WithDetailing); (это тоже освоил :) )

4) а вот и самое интресное... как мне теперь выбрать именно тот новый скопированный вид, и как его разместить именно на лист, который опять же хочу спросит у пользоваетля
(как спросить лист тоже не знаю... ведь лист как таковой нельзя выделить типа выберте лист... можно только что бы пользоваетль выбрал какой то сделал его активным а потом вставить в активный... так вот как прервать выполнени на время пока пользователь счелкает по листам и выбирает нужный ему лист? )
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Андрей Фазлеев от 10-02-2016, 12:38:57
4) а вот и самое интресное... как мне теперь выбрать именно тот новый скопированный вид, и как его разместить именно на лист, который опять же хочу спросит у пользоваетля
(как спросить лист тоже не знаю... ведь лист как таковой нельзя выделить типа выберте лист... можно только что бы пользоваетль выбрал какой то сделал его активным а потом вставить в активный... так вот как прервать выполнени на время пока пользователь счелкает по листам и выбирает нужный ему лист? )


Выбирать скопированный вид не требуется. Метод Duplicate возвращает Id нового вида:

Код - C# [Выбрать]
  1.                         ElementId duplicatedViewId = v.Duplicate(ViewDuplicateOption.WithDetailing);
  2.                        
  3.                         View duplicatedView = (View)doc.GetElement(duplicatedViewId);

Список листов для размещения придётся получить через фильтр и вывести в диалоговое окошко или фильтровать его из документа по заданным критериям, другого пути выбора я пока не нашёл.

Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: sniip от 10-02-2016, 12:41:05
Не прошло и 5ти часов как получилась первая программа:


Код - C# [Выбрать]
  1. UIApplication uiApp = this.Application;
  2.             Document doc = uiApp.ActiveUIDocument.Document;
  3.                 Transaction trans = new Transaction(doc);
  4.             trans.Start("Lab");
  5.            
  6.             Selection sel = uiApp.ActiveUIDocument.Selection;
  7.             ICollection<ElementId> elementSet = sel.GetElementIds();
  8.                        
  9.             var elem1 = elementSet.First();
  10.                      
  11.             Viewport viewPort1;
  12.             viewPort1=doc.GetElement(elem1) as Viewport;
  13.                    
  14.                      
  15.             View view1;            
  16.             view1=doc.GetElement(viewPort1.ViewId) as View;
  17.            
  18.             var newview = view1.Duplicate(ViewDuplicateOption.WithDetailing);          
  19.                                    
  20.             XYZ point;            
  21.             point = new XYZ(0, 0, 0);  
  22.                                
  23.             Viewport.Create(doc, viewPort1.SheetId, newview ,  point);
  24.                
  25.             trans.Commit();
  26.  

Выбираем вид на листе.. и вуаля... в точке 0,0 вставляется копия такого же вида с детализацией) круто)))

что не получилось:
1) бился бился с get_BoundingBox но так ничего и не вышло.. ошибки ошибки ошибки..
Подскажите как на пример моей программы новый вид вставить на лист относительно старого со смещением? как вытащить координаты старого вида? того который копировал?


2) как скопировать таким же образом спецификацию? (решил вопрос сам, если нужно выложу)

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

4) Хмм.. еще с одной проблемой столкнулся... приложения писал ввиде макросов в стандартном редакторе. потом решил оформить ввиде кнопки... создал файл *.addin но запустить приложение не получается... пишет типа проблма с классом.
так у меня в программе только функции... как на них ссылку седлать?
проблема в этой строчке:

<FullClassName>PipeCreation.Command</FullClassName>

у меня так:


Код - C# [Выбрать]
  1. public partial class ThisDocument
  2.         {
  3.                 private void Module_Startup(object sender, EventArgs e)
  4.                 {
  5.  
  6.                 }
  7.  
  8.                 private void Module_Shutdown(object sender, EventArgs e)
  9.                 {
  10.  
  11.                 }
  12.  
  13.                 #region Revit Macros generated code
  14.                 private void InternalStartup()
  15.                 {
  16.                         this.Startup += new System.EventHandler(Module_Startup);
  17.                         this.Shutdown += new System.EventHandler(Module_Shutdown);
  18.                 }
  19.                 #endregion
  20.                 public void KOPIROVANIE()
  21.                 {
  22.                  ...........................
  23.                 }
  24.         }
  25. }
как эта строчка будет выглядеть у меня?
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Андрей Бушман от 10-02-2016, 18:13:27
Не прошло и 5ти часов как получилась первая программа
Я не программирую под Revit, однако по диагонали просмотрев твой код, у меня возникает ряд сомнений (возможно ошибочных, т.к. AutoCAD - это всё же не Revit) в его качестве:

1. Если в Revit, класс Transaction реализует IDisposable, подобно тому, как это обстоит в AutoCAD, то использование блока using напрашивается само собой.

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

P.S. Освой подсветку синтаксиса в коде, который выкладываешь на форум.
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Александр Ривилис от 10-02-2016, 19:21:16
sniip,
Пока хромает форматирование кода для форума. Посмотри как это делать у меня в подписи.
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Андрей Фазлеев от 11-02-2016, 13:11:44
4) Хмм.. еще с одной проблемой столкнулся... приложения писал ввиде макросов в стандартном редакторе. потом решил оформить ввиде кнопки... создал файл *.addin но запустить приложение не получается... пишет типа проблма с классом.
так у меня в программе только функции... как на них ссылку седлать?

Я стартую проекты с шаблона Jeremy Tammik'а. При создании проекта генерируется файл addin, плагин готов к запуску в Revit.
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Виктор Чекалин от 12-02-2016, 19:01:40
Задержался я с ответом:)
Мне нужно задать пользователю вопрос: выберите вид (если он на листе то он типа VIewport как я понял)
пробую таким образом:
Код - C# [Выбрать]
GetElement(uiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Face,"выберите вид"))
   а) можно ли таким образом вести диалог с пользоваетелм?
   б) как тип Element преобразовать в тип VIewport?
ObjectType.Face говорит о том, что пользователь должен выбрать поверхность элемента. Интересно, почему вы решили, что нужно именно его?:)
В целом, для выбора листа такой метод не подойдет. Метод PickObject предполагает выбор чего либо в модели, а лист придется выбирать из диспетчера проектов. Андрей правильно сказал, что нужно реализовывать свой диалог выбора листа.

Далее. Viewport - это не лист. Viewport - это вид на листе.
Преобразовать Element в какой-либо другой тип не получится, а вот привести его к другому типу, если он таковым является, можно с помощью конструкции as. Например,
Код - C# [Выбрать]
  1. Viewport viewport =  element as Viewport;

программа не запустилась но я думаю это единственная чать которая у меня получилась:)
В этом случае логичнее привести ошибку.
Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Виктор Чекалин от 12-02-2016, 19:10:47
Selection sel = uiApp.ActiveUIDocument.Selection;
            ICollection<ElementId> elementSet = sel.GetElementIds();
                       
            var elem1 = elementSet.First();
                     
            Viewport viewPort1;
            viewPort1=doc.GetElement(elem1) as Viewport;
                   
                     
            View view1;            
            view1=doc.GetElement(viewPort1.ViewId) as View;
Чтобы получить вид, можно было просто взять текущий, без использования Viewport.  uiApp.ActiveUIDocument.Document.ActiveView.
Хотя далее вы все равно использовали выбранный Viewport, так что ваш вариант тоже нормальный.
бился бился с get_BoundingBox но так ничего и не вышло.. ошибки ошибки ошибки..
Подскажите как на пример моей программы новый вид вставить на лист относительно старого со смещением? как вытащить координаты старого вида? того который копировал?
BoundingBox здесь конечно не подходит.
На сайте есть несколько статей по этому поводу. Например, вот:
Определение размера и месторасположения видов на листе (http://adn-cis.org/opredelenie-razmera-i-mestoraspolozheniya-vidov-na-liste.html)
Как получить позицию вида на листе (http://adn-cis.org/kak-poluchit-pozicziyu-vida-na-liste.html)
Проблема с расположением двух и более видов на листе и ее решение (http://adn-cis.org/problema-s-raspolozheniem-dvux-i-bolee-vidov-na-liste-i-ee-reshenie.html)
Преобразование координат листа в координаты модели (http://adn-cis.org/preobrazovanie-koordinat-lista-v-koordinatyi-modeli.html)
Думаю вы найдете там необходимую информацию.

Название: Re: Копирование спецификации или вида из пространства листа.
Отправлено: Виктор Чекалин от 12-02-2016, 19:12:58
Если в Revit, класс Transaction реализует IDisposable, подобно тому, как это обстоит в AutoCAD, то использование блока using напрашивается само собой.
поддержу. Именно так и нужно делать.
Если возможна ситуация, когда активный документ может быть равен null (как это имеет место быть в AutoCAD), то и здесь напрашивается соответствующая предварительная проверка.
Да, активного документа может и не быть, но в данном случае до макроса будет не добраться, когда нет активного документа.