Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()

Автор Тема: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()  (Прочитано 10428 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Пытаюсь использовать этот метод, получаю Fatalerror и Acad падает
Что я делаю не так?
Код - C# [Выбрать]
  1.         [CommandMethod("CloneLayout")]
  2.         public static void CloneLayout()
  3.         {
  4.             // Get the current document and database
  5.             Document acDoc = Application.DocumentManager.MdiActiveDocument;
  6.             Database acCurDb = acDoc.Database;
  7.  
  8.             // Get the layout and plot settings of the named pagesetup
  9.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  10.             {
  11.                 // Reference the Layout Manager
  12.                 LayoutManager acLayoutMgr = LayoutManager.Current;
  13.  
  14.                 // Create the new layout with default settings
  15.                 int npoz = acLayoutMgr.LayoutCount;
  16.                 string newLayoutName = "test1";
  17.                 acLayoutMgr.CloneLayout("tempLayout", newLayoutName, npoz);
  18.  
  19.                 //
  20.                 acDoc.Editor.WriteMessage("\nstep1: ");
  21.                 ObjectId newLayoutID = acLayoutMgr.GetLayoutId("tempLayout");
  22.                 acDoc.Editor.WriteMessage("\nstep2: ");
  23.                 Layout acLayout = acTrans.GetObject(newLayoutID, OpenMode.ForRead) as Layout;
  24.                 acDoc.Editor.WriteMessage("\nstep3: ");
  25.                 ObjectIdCollection wViewports = acLayout.GetViewports();
  26.                 acDoc.Editor.WriteMessage("\nstep4: ");
  27.                 Viewport  wVP = acTrans.GetObject(wViewports[0], OpenMode.ForRead) as Viewport;
  28.                 acDoc.Editor.WriteMessage("\nCenterPoint: " + wVP.CenterPoint.ToString());
  29.  
  30.                 // Save the changes made
  31.                 acTrans.Commit();
  32.             }
  33.  
  34.         }

Пока попробую использоватиь код отсюда
« Последнее редактирование: 28-05-2015, 10:36:30 от trir »

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #1 : 27-05-2015, 12:11:04 »
using (acDoc.LockDocument()) { }

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

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #2 : 27-05-2015, 12:19:12 »
Спасибо, действительно
даже в голову не пришло...  :-\

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #3 : 27-05-2015, 15:38:33 »
using (acDoc.LockDocument()) { }
Это если функция CloneLayout вызывается из контекста приложения, а не как команда _CloneLayout, то блокировка нужна. В противном случае это лишнее. И на Fatal Error никак не влияет.
« Последнее редактирование: 28-05-2015, 00:13:40 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение trir 28-05-2015, 11:09:04

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #4 : 27-05-2015, 16:02:32 »
trir
Посмотрел внимательнее на код и переделал его. Теперь не "фаталит". Обрати внимание на мои комментарии:
Код - C# [Выбрать]
  1. [CommandMethod("CloneLayout")]
  2. public static void CloneLayout()
  3. {
  4.   // Get the current document and database
  5.   Document acDoc = Application.DocumentManager.MdiActiveDocument;
  6.   Database acCurDb = acDoc.Database;
  7.  
  8.   using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  9.   {
  10.     // Reference the Layout Manager
  11.     LayoutManager acLayoutMgr = LayoutManager.Current;
  12.  
  13.     // Create the new layout with default settings
  14.     int npoz = acLayoutMgr.LayoutCount;
  15.     string newLayoutName = "test1";
  16.     acLayoutMgr.CloneLayout("tempLayout", newLayoutName, npoz);
  17.  
  18.     //
  19.     acDoc.Editor.WriteMessage("\nstep1: ");
  20.     // Получаешь ObjectId __исходного__ Layout, а не копии и дальше работаешь с ним?
  21.     // Тогда зачем ты клонировал исходный Layout???
  22.     ObjectId newLayoutID = acLayoutMgr.GetLayoutId("tempLayout");
  23.     acDoc.Editor.WriteMessage("\nstep2: ");
  24.     Layout acLayout = acTrans.GetObject(newLayoutID, OpenMode.ForRead) as Layout;
  25.     acDoc.Editor.WriteMessage("\nstep3: ");
  26.     ObjectIdCollection wViewports = acLayout.GetViewports();
  27.     //////////////////////////////////////////////////////////////////////////
  28.     //  Если еще нет ни одного Viewport у Layout,
  29.     //  то нужно его инициализировать
  30.     //////////////////////////////////////////////////////////////////////////
  31.     if (wViewports.Count == 0) {
  32.       acLayout.UpgradeOpen();
  33.       acLayout.Initialize();
  34.       acLayout.DowngradeOpen();
  35.       wViewports = acLayout.GetViewports();
  36.     }
  37.     //////////////////////////////////////////////////////////////////////////
  38.     acDoc.Editor.WriteMessage("\nstep4: ");
  39.     Viewport wVP = acTrans.GetObject(wViewports[0], OpenMode.ForRead) as Viewport;
  40.     acDoc.Editor.WriteMessage("\nCenterPoint: " + wVP.CenterPoint.ToString());
  41.  
  42.     // Save the changes made
  43.     acTrans.Commit();
  44.   }
  45. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #5 : 28-05-2015, 08:03:13 »
Без разницы какой лист беру, на методе GetViewports() получаю фатал, поэтому до проверки просто не дойду. И зачем обновлять сушествующий лист?
Ещё, на листы созданные через CloneLayout() нельзя переключится с модели, сначала надо переключится на существующий лист, а потом на новые...

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #6 : 28-05-2015, 09:14:37 »
В том коде, который ты показал, Fatal Error у меня был на строке
Код - C# [Выбрать]
  1. Viewport wVP = acTrans.GetObject(wViewports[0], OpenMode.ForRead) as Viewport;
по причине того, что ни одного Viewport в acLayout нет.
P.S.: На всякий случай вызови acLayout.Initialize() до вызова acLayout.GetViewports();

Ещё, на листы созданные через CloneLayout() нельзя переключится с модели, сначала надо переключится на существующий лист, а потом на новые...
Не могу подтвердить. Если для нового листа был вызов acLayout.Initialize(), то у меня прекрасно переключается на созданный CloneLayout лист.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #7 : 28-05-2015, 10:32:34 »
Чем дальше - тем веселее
Цитировать
Autodesk.AutoCAD.Runtime.Exception: eInvalidContext
   в Autodesk.AutoCAD.DatabaseServices.Layout.Initialize()

Код - C# [Выбрать]
  1.                 acDoc.Editor.WriteMessage("\nstep3: ");
  2.                 if (acLayout != null) {
  3.                     acLayout.UpgradeOpen();
  4.                     acLayout.Initialize();
  5.                     acLayout.DowngradeOpen();
  6.                     ObjectIdCollection wViewports = acLayout.GetViewports();
  7.                     acDoc.Editor.WriteMessage("\nstep4: ");
  8.                     Viewport wVP = acTrans.GetObject(wViewports[1], OpenMode.ForRead) as Viewport;
  9.                     acDoc.Editor.WriteMessage("\nCenterPoint: " + wVP.CenterPoint.ToString());
  10.                 }
  11.                 else acDoc.Editor.WriteMessage("\nerr1: ");

AutoCAD 2015

У меня видовые экраны есть, затем и копирую "шаблон". Между прочим - а разве можно создать лист без видового экрана? Штатными средствами - нельзя, и даже на VBA на новом листе всегда есть "невидимый" видовой экран

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #8 : 28-05-2015, 10:49:23 »
trir,
1) Ты можешь ответить работает ли исправленный мной код у тебя или нет?
2) Если не работает, то как это выглядит? И выложи чертеж на котором происходит сбой.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #9 : 28-05-2015, 10:50:08 »
Между прочим - а разве можно создать лист без видового экрана?
Программно можно.
Посмотри этот код: http://adn-cis.org/forum/index.php?topic=2723.msg9499#msg9499
Да и вообще вся тема аналогична твоей.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #10 : 28-05-2015, 10:57:37 »
Работает

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #11 : 28-05-2015, 10:58:20 »
Работает
Так в чем проблема???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #12 : 28-05-2015, 11:07:58 »
Не пойму всей механики, но от строчки:
Код - C# [Выбрать]
  1. newViewPortId = newLayout.Initialize();
я в осадке, и начинаю понимать...
P.S. А где нибудь есть документация в которой описанно - что возвращает newLayout.Initialize();

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
« Ответ #13 : 28-05-2015, 11:43:54 »
P.S. А где нибудь есть документация в которой описанно - что возвращает newLayout.Initialize();
Конечно. В документации ObjectARX SDK. Возвращает ObjectId основного Viewport для Layout:
Цитировать
This method will do the behind the scenes work to establish a Paper Space viewport for the layout. This allows a layout to be set up and made ready for other viewports and entities to be put into the layout as well as to set various layout properties.

Returns an existing ObjectId object that will be set to the objectId of the paper space Viewport created by this function

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение