Копирование спецификации или вида из пространства листа.

Автор Тема: Копирование спецификации или вида из пространства листа.  (Прочитано 10590 раз)

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

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

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
Здравствуйте, пытаюсь решить следующую задачу. Есть вид и спецификация вынесенная на лист. Хочу написать макрос по которому у пользователя спрашивается вид или спецификация. Далее вид копируется с детализацией (или копируется спецификация) и у пользователя спрашивается точка. Новый вид/ спецификация вставляется в нужную точку на листе...

как вариант полное копирование листа, но все элементы что бы становились новыми т.е. скопированные.

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
sniip, день добрый.

В Revit API есть метод по копированию вида - View.Duplicate. Он делает то же самое, что и в пользовательском интерфейсе команда Дублировать. Однако, эта команда не доступна для листов. В таком случае, придется реализовывать функцию копирования самому.
Первое что приходит в голову, создать новый лист, найти все спецификации на исходном листе и с помощью ElementTransformUtils.CopyElement вставить скопировать спецификации на новый лист.

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

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
А как разместить вид созданный на листе?

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
А как разместить вид созданный на листе?
С помощью статического метода Viewport.Create()

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

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
Я совершенно запутался)) нужна помощь (сразу скажу что это моя первая программ в ревите, сильно не ругайте)
попробую структурировать все вопросы:
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) а вот и самое интресное... как мне теперь выбрать именно тот новый скопированный вид, и как его разместить именно на лист, который опять же хочу спросит у пользоваетля
(как спросить лист тоже не знаю... ведь лист как таковой нельзя выделить типа выберте лист... можно только что бы пользоваетль выбрал какой то сделал его активным а потом вставить в активный... так вот как прервать выполнени на время пока пользователь счелкает по листам и выбирает нужный ему лист? )
« Последнее редактирование: 09-02-2016, 00:28:07 от Александр Ривилис »

Оффлайн Андрей Фазлеев

  • ADN Club
  • Сообщений: 24
  • Карма: 8
    • Andrey Stroitel
4) а вот и самое интресное... как мне теперь выбрать именно тот новый скопированный вид, и как его разместить именно на лист, который опять же хочу спросит у пользоваетля
(как спросить лист тоже не знаю... ведь лист как таковой нельзя выделить типа выберте лист... можно только что бы пользоваетль выбрал какой то сделал его активным а потом вставить в активный... так вот как прервать выполнени на время пока пользователь счелкает по листам и выбирает нужный ему лист? )


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

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

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


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

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
Не прошло и 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. }
как эта строчка будет выглядеть у меня?
« Последнее редактирование: 10-02-2016, 19:19:38 от Александр Ривилис »

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Не прошло и 5ти часов как получилась первая программа
Я не программирую под Revit, однако по диагонали просмотрев твой код, у меня возникает ряд сомнений (возможно ошибочных, т.к. AutoCAD - это всё же не Revit) в его качестве:

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

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

P.S. Освой подсветку синтаксиса в коде, который выкладываешь на форум.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
sniip,
Пока хромает форматирование кода для форума. Посмотри как это делать у меня в подписи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Фазлеев

  • ADN Club
  • Сообщений: 24
  • Карма: 8
    • Andrey Stroitel
4) Хмм.. еще с одной проблемой столкнулся... приложения писал ввиде макросов в стандартном редакторе. потом решил оформить ввиде кнопки... создал файл *.addin но запустить приложение не получается... пишет типа проблма с классом.
так у меня в программе только функции... как на них ссылку седлать?

Я стартую проекты с шаблона Jeremy Tammik'а. При создании проекта генерируется файл addin, плагин готов к запуску в Revit.

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Задержался я с ответом:)
Мне нужно задать пользователю вопрос: выберите вид (если он на листе то он типа 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;

программа не запустилась но я думаю это единственная чать которая у меня получилась:)
В этом случае логичнее привести ошибку.

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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
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 здесь конечно не подходит.
На сайте есть несколько статей по этому поводу. Например, вот:
Определение размера и месторасположения видов на листе
Как получить позицию вида на листе
Проблема с расположением двух и более видов на листе и ее решение
Преобразование координат листа в координаты модели
Думаю вы найдете там необходимую информацию.


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

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Если в Revit, класс Transaction реализует IDisposable, подобно тому, как это обстоит в AutoCAD, то использование блока using напрашивается само собой.
поддержу. Именно так и нужно делать.
Если возможна ситуация, когда активный документ может быть равен null (как это имеет место быть в AutoCAD), то и здесь напрашивается соответствующая предварительная проверка.
Да, активного документа может и не быть, но в данном случае до макроса будет не добраться, когда нет активного документа.