Обновление границ печати (MediaBounds) в пространстве листа и его extents.

Автор Тема: Обновление границ печати (MediaBounds) в пространстве листа и его extents.  (Прочитано 5150 раз)

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

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

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

  • ADN OPEN
  • ***
  • Сообщений: 150
  • Карма: 3
Добрый день! Всех с наступающим!При изменении границ печати и их местоположения, при выполнении кода границы не меняются. Вероятно требуется обновление наподобие обновления границ в модели Database.UpdateExt. Как обновить MediaBounds и Еxtents в пространстве листа?
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.PlottingServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. namespace pavps
  7. {
  8.     public class pavps
  9.     {
  10.         [CommandMethod("PAVPS")]
  11.         public void Run()
  12.         {
  13.             Document acDoc = Application.DocumentManager.MdiActiveDocument;
  14.             Database acCurDb = acDoc.Database;
  15.             Editor ed = acDoc.Editor;
  16.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  17.             {
  18.                 LayoutManager acLayoutMgr = LayoutManager.Current;
  19.                 Layout acLayout = acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout), OpenMode.ForRead) as Layout;
  20.                 acDoc.Editor.WriteMessage("\nCurrent layout: " + acLayout.LayoutName);
  21.                 acDoc.Editor.WriteMessage("\nCurrent device name: " + acLayout.PlotConfigurationName);
  22.                 PlotInfo acPlInfo = new PlotInfo();
  23.                 acPlInfo.Layout = acLayout.ObjectId;
  24.                 PlotSettings acPlSet = new PlotSettings(false);
  25.                 acLayout.UpgradeOpen();
  26.                 acPlSet.CopyFrom(acLayout);
  27.                 PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;
  28.                 // var plotConfig = acPlInfo.ValidatedConfig;
  29.                 PlotConfig plotConfig = PlotConfigManager.SetCurrentConfig(acLayout.PlotConfigurationName);
  30.                 acPlSetVdr.SetPlotConfigurationName(acPlSet, acLayout.PlotConfigurationName, null);
  31.                 //PlotConfig plotConfig = PlotConfigManager.CurrentConfig;
  32.                 var canonicalName = acPlSet.CanonicalMediaName;
  33.                 var localName = plotConfig.GetLocalMediaName(canonicalName);
  34.                 var mediaBounds = plotConfig.GetMediaBounds(canonicalName);
  35.                 var pageSize = mediaBounds.PageSize;
  36.                 var left1 = mediaBounds.LowerLeftPrintableArea;
  37.                 var right1 = mediaBounds.UpperRightPrintableArea;
  38.                 Extents3d ext = acLayout.Extents;
  39.                 Extents2d lim = acLayout.Limits;
  40.                 ObjectIdCollection vPortsIds = new ObjectIdCollection();
  41.                 vPortsIds = acLayout.GetViewports();
  42.                 Viewport viewport = acTrans.GetObject(vPortsIds[0], OpenMode.ForRead) as Viewport;
  43.                 Extents3d vpExts = viewport.GeometricExtents;
  44.  
  45.                 ed.WriteMessage("\n" + vpExts.ToString());
  46.                 ed.WriteMessage("\n" + ext.ToString());
  47.                 ed.WriteMessage("\n" + lim.ToString());
  48.                 ed.WriteMessage("\n" + pageSize.X.ToString());
  49.                 ed.WriteMessage("\n" + pageSize.Y.ToString());
  50.                 ed.WriteMessage("\n" + left1.X.ToString());
  51.                 ed.WriteMessage("\n" + left1.Y.ToString());
  52.                 ed.WriteMessage("\n" + right1.X.ToString());
  53.                 ed.WriteMessage("\n" + right1.Y.ToString());
  54.                 ed.WriteMessage("\n" + canonicalName.ToString());
  55.                 ed.WriteMessage("\n" + localName.ToString());
  56.                 acTrans.Commit();
  57.             }
  58.  
  59.         }
  60.     }
  61. }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
При изменении границ печати и их местоположения, при выполнении кода границы не меняются. Вероятно требуется обновление наподобие обновления границ в модели Database.UpdateExt. Как обновить MediaBounds и Еxtents в пространстве листа?
Честно говоря я не понял чего именно ты добиваешься. В любом случае все манипуляции с acPlSet ты делаешь "на лету" не возвращая их в acLayout (т.е. сам Layout ты не меняешь).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 150
  • Карма: 3
Если я вас правильно понял, то добавив acLayout.CopyFrom(acPlSet), код начинает работать,как я задумывал, но только наполовину (меняются форматы, имена принтеров), а вот абсолютные координаты acLayout.Extents и acLayout.Limits не меняются.
То есть работа должна быть такой: запускаем код, с первого раза все выводится в строки как нужно (абсолютные координаты соответствуют действительности),затем вручную в редакторе меняем местоположение примитивов, меняем формат печати,имена принтеров итд.,запускаем код второй раз и вот тут в некоторых строках выводится старая информация (не обновляется Database документа?). При закрытии документа (не редактора) и повторном открытии и запуске кода выводится уже новая информация в строки. Никак не могу сообразить, что нужно сделать, чтобы за одну сессию менялась вся информация при повторном запуске. :(


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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
а вот абсолютные координаты acLayout.Extents и acLayout.Limits не меняются.
А чего они должны меняться? И вообще покажи итоговый код, запиши видео как у меня указано в подписи. Пока я не могу понять чего ты пытаешься добиться.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 150
  • Карма: 3
А чего они должны меняться?
Наверное уже и не должны :) особенно если в документации про Layout.Extents (Accesses the current extents setting of the layout. This value may not be the actual extents of the geometry in the layout, it is just the value last saved in the layout).

Но на всякий случай код (выкинул что работает, оставил что мне непонятно):
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. namespace pavps
  6. {
  7.     public class pavps
  8.     {
  9.         [CommandMethod("PAVPS")]
  10.         public void Run()
  11.         {
  12.             Document acDoc = Application.DocumentManager.MdiActiveDocument;
  13.             Database acCurDb = acDoc.Database;
  14.             Editor ed = acDoc.Editor;
  15.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  16.             {
  17.                 LayoutManager acLayoutMgr = LayoutManager.Current;
  18.                 Layout acLayout = acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout), OpenMode.ForWrite) as Layout;
  19.                 Extents3d ext = acLayout.Extents;
  20.                 acTrans.Commit();
  21.                 ed.WriteMessage("\n" + ext.ToString());
  22.             }
  23.         }
  24.     }
  25. }

Видео не получается пока записать, но из картинок надеюсь понятнее выйдет.
Extents, если я правильно понял, пунктирная рамка в Layout.
Точки с координатами в layout в виде полей для понимания "размерностей" координат.
Запускаем код:
Картинка 1 (координаты в комстроке.Тут все ОК)

Переносим точки произвольно(вручную),Ctrl-P,Extents,Apply to Layout,Regen, запускаем код повторно:
Картинка 2 (координаты точек изменились,в комстроке старые координаты)

Close(документ, Autocad не закрываем),Save,Open File,запускаем код:
Картинка 3 (Все ОК.В комстроке новые координаты):


Вопрос: возможно ли получить результат картинки 3, не закрывая документ?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Extents, если я правильно понял, пунктирная рамка в Layout.
Вообще-то это то, что называется Plot paper size.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 150
  • Карма: 3
Вообще-то это то, что называется Plot paper size.
Вы правы, а также еще называется printable area, plot area, plot boundary... Просто в моем случае координаты выводимые Layout.Extents совпадают с координатами этой пунктирной рамки.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А зачем тебе вообще Layout.Extents? Без него ты обойтись не можешь? Тебе нужно вычислить размеры и положение этой рамки? Для этого есть Database.Pextmin и Database.Pextmax:
Код - C# [Выбрать]
  1. [CommandMethod("UpdatePSpaceExts")]
  2. public void UpdatePSpaceExts()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   Database db = doc.Database;
  6.   Editor ed = doc.Editor;
  7.   // Проверяем в пространстве ли листа мы
  8.   if (db.TileMode == true)
  9.     return;
  10.  
  11.   using (Transaction tr = db.TransactionManager.StartTransaction())
  12.   {
  13.     // BlockTableRecord для текущего пространства
  14.     BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord;
  15.     // Текущий лист
  16.     Layout layout = tr.GetObject(btr.LayoutId, OpenMode.ForRead) as Layout;
  17.     // Главный Viewport листа
  18.     ObjectId mainPSpaceVportId = layout.GetViewports()[0];
  19.  
  20.     // Перебираем все примитивы листа, кроме главного Viewport
  21.     Extents3d extents = new Extents3d();
  22.     foreach (ObjectId id in btr)
  23.     {
  24.       if (id != mainPSpaceVportId)
  25.       {
  26.         Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
  27.         if (ent != null)
  28.           try
  29.           {
  30.             extents.AddExtents(ent.GeometricExtents);
  31.           } catch { };
  32.       }
  33.     }
  34.  
  35.     // Создаём Extents3d на основе лимитов листа.
  36.     Extents3d limits = new Extents3d(
  37.           new Point3d(layout.Limits.MinPoint.X, layout.Limits.MinPoint.Y, 0),
  38.           new Point3d(layout.Limits.MaxPoint.X, layout.Limits.MaxPoint.Y, 0));
  39.     extents.AddExtents(limits);
  40.  
  41.     // Обновляем Pextmin и Pextmax.
  42.     db.Pextmin = extents.MinPoint;
  43.     db.Pextmax = extents.MaxPoint;
  44.  
  45.     tr.Commit();
  46.   }
  47. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение pavka_97 15-01-2019, 15:42:47

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробуй еще такой вариант. У меня он обновляет Layout.Extents без переоткрытия чертежа. Обновление идёт за счет переключения текущего листа (для простоты переключаю на модель и обратно):
Код - C# [Выбрать]
  1. [CommandMethod("UpdatePSpaceExts")]
  2. public void UpdatePSpaceExts()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   Database db = doc.Database;
  6.   Editor ed = doc.Editor;
  7.   // Проверяем в пространстве ли листа мы
  8.   if (db.TileMode == true)
  9.     return;
  10.   string curLayoutName = LayoutManager.Current.CurrentLayout;
  11.   string msLayoutName = "";
  12.   using (Transaction tr = db.TransactionManager.StartTransaction())
  13.   {
  14.     // BlockTableRecord для текущего пространства
  15.     BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord;
  16.     BlockTableRecord btrMS = tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead) as BlockTableRecord;
  17.     // Текущий лист
  18.     Layout layout = tr.GetObject(btr.LayoutId, OpenMode.ForRead) as Layout;
  19.     // Лист модели
  20.     Layout layoutMS = tr.GetObject(btrMS.LayoutId, OpenMode.ForRead) as Layout;
  21.     msLayoutName = layoutMS.LayoutName;
  22.     // Главный Viewport листа
  23.     // # Note: First ObjectId from GetViewports() is the main paper space area Viewport ObjectId.
  24.     ObjectId mainPSpaceVportId = layout.GetViewports()[0];
  25.  
  26.     // Перебираем все примитивы листа, кроме главного Viewport
  27.     // # Note: Exclude main paper space viewport ObjectId.
  28.     Extents3d extents = new Extents3d();
  29.     foreach (ObjectId id in btr)
  30.     {
  31.       if (id != mainPSpaceVportId)
  32.       {
  33.         Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
  34.         if (ent != null)
  35.           try
  36.           {
  37.             extents.AddExtents(ent.GeometricExtents);
  38.           } catch { };
  39.       }
  40.     }
  41.  
  42.     // Создаём Extents3d на основе лимитов листа.
  43.     Extents3d limits = new Extents3d(
  44.           new Point3d(layout.Limits.MinPoint.X, layout.Limits.MinPoint.Y, 0),
  45.           new Point3d(layout.Limits.MaxPoint.X, layout.Limits.MaxPoint.Y, 0));
  46.     extents.AddExtents(limits);
  47.  
  48.     // Обновляем Pextmin и Pextmax.
  49.     db.Pextmin = extents.MinPoint;
  50.     db.Pextmax = extents.MaxPoint;
  51.     db.UpdateExt(true);
  52.     tr.Commit();
  53.   }
  54.   // Это переключение Лист->Модель->Лист обновляет Layout.Extents
  55.   LayoutManager.Current.CurrentLayout = msLayoutName;
  56.   LayoutManager.Current.CurrentLayout = curLayoutName;
  57.  
  58. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 150
  • Карма: 3
Да, второй вариант рабочий, хоть и не без переключений.