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

ADN Club => AutoCAD .NET API => Тема начата: trir от 27-05-2015, 11:16:09

Название: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: trir от 27-05-2015, 11:16:09
Пытаюсь использовать этот метод, получаю 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.         }

Пока попробую использоватиь код отсюда (http://adndevblog.typepad.com/autocad/2012/08/changing-zoom-in-paperspace-viewport.html)
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Пекшев aka Modis от 27-05-2015, 12:11:04
using (acDoc.LockDocument()) { }
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: trir от 27-05-2015, 12:19:12
Спасибо, действительно
даже в голову не пришло...  :-\
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 27-05-2015, 15:38:33
using (acDoc.LockDocument()) { }
Это если функция CloneLayout вызывается из контекста приложения, а не как команда _CloneLayout, то блокировка нужна. В противном случае это лишнее. И на Fatal Error никак не влияет.
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 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. }
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: trir от 28-05-2015, 08:03:13
Без разницы какой лист беру, на методе GetViewports() получаю фатал, поэтому до проверки просто не дойду. И зачем обновлять сушествующий лист?
Ещё, на листы созданные через CloneLayout() нельзя переключится с модели, сначала надо переключится на существующий лист, а потом на новые...
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 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 лист.
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: trir от 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 на новом листе всегда есть "невидимый" видовой экран
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 28-05-2015, 10:49:23
trir,
1) Ты можешь ответить работает ли исправленный мной код у тебя или нет?
2) Если не работает, то как это выглядит? И выложи чертеж на котором происходит сбой.
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 28-05-2015, 10:50:08
Между прочим - а разве можно создать лист без видового экрана?
Программно можно.
Посмотри этот код: http://adn-cis.org/forum/index.php?topic=2723.msg9499#msg9499
Да и вообще вся тема аналогична твоей.
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: trir от 28-05-2015, 10:57:37
Работает
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 28-05-2015, 10:58:20
Работает
Так в чем проблема???
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: trir от 28-05-2015, 11:07:58
Не пойму всей механики, но от строчки:
Код - C# [Выбрать]
  1. newViewPortId = newLayout.Initialize();
я в осадке, и начинаю понимать...
P.S. А где нибудь есть документация в которой описанно - что возвращает newLayout.Initialize();
Название: Re: Autodesk.AutoCAD.DatabaseServices.Layout.GetViewports()
Отправлено: Александр Ривилис от 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