Создание Layout

Автор Тема: Создание Layout  (Прочитано 7296 раз)

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Создание Layout
« : 31-03-2020, 13:40:54 »
Всех приветствую.
В процессе работы возник вопрос, а возможно ли создавать layout и манипулировать настройками его вьюпортов, не переключаясь на него? После создания layout в его базе 0 вьюпортов, но если туда добавить свои вьюпорты, то после переключения их становится уже 4.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Создание Layout
« Ответ #1 : 31-03-2020, 14:02:25 »
Можно. Я копированием всех объектов из файла шаблона создаю рамку и вьюпорты. Проблем никаких не возникало.

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #2 : 31-03-2020, 14:27:08 »
Можно. Я копированием всех объектов из файла шаблона создаю рамку и вьюпорты. Проблем никаких не возникало.
А можно небольшой пример?

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Создание Layout
« Ответ #3 : 31-03-2020, 15:32:12 »
Код - C# [Выбрать]
  1.     /// <summary>
  2.     /// Вставка листа из шаблона в активный документ
  3.     /// Ни в коем случае нельзя вызывать, если открыта хоть одна транзакция!!
  4.     /// </summary>
  5.     /// <param name="temlate"> база данных шаблона. dwg должен быть уже прочитан </param>
  6.     /// <param name="sourceLayoutName"> копируемый лист. должен быть в шаблоне </param>
  7.     /// <param name="newLayoutName"> новое имя листа. оставьте пустым чтоб генерировать автоматом </param>
  8.     internal static ObjectId NewLayout(Database template, string sourceLayoutName, string newLayoutName = "")
  9.     {
  10.       ObjectId newID = new ObjectId();
  11.       Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  12.       if (doc is null) return ObjectId.Null;
  13.       Database curDb = doc.Database;
  14.       using (Transaction templateTrans = template.TransactionManager.StartTransaction())
  15.       {
  16.         DBDictionary templateDict = (DBDictionary)templateTrans.GetObject(template.LayoutDictionaryId, OpenMode.ForRead);
  17.         if (!templateDict.Contains(sourceLayoutName))
  18.           return ObjectId.Null;
  19.         Layout templateLayout = (Layout)templateTrans.GetObject(templateDict.GetAt(sourceLayoutName), OpenMode.ForRead);
  20.         using (Transaction curTrans = curDb.TransactionManager.StartTransaction())
  21.         {
  22.           DBDictionary curLayoutDict = (DBDictionary)curTrans.GetObject(curDb.LayoutDictionaryId, OpenMode.ForRead);
  23.           if (newLayoutName == "") //сгенерим новое имя
  24.           {
  25.             if (!curLayoutDict.Contains(sourceLayoutName)) newLayoutName = sourceLayoutName;
  26.             else newLayoutName = NewName(sourceLayoutName, curLayoutDict);
  27.           }
  28.           curTrans.Commit();
  29.         } // закрываем curTrans временно для вызова CreateLayout
  30.  
  31.         using (doc.LockDocument())
  32.         {
  33.           newID = LayoutManager.Current.CreateLayout(newLayoutName); // надо вызывать c блокировкой документа, но вне транзакции!
  34.           using Transaction curTrans = curDb.TransactionManager.StartTransaction();
  35.           DBDictionary curLayoutDict = (DBDictionary)curTrans.GetObject(curDb.LayoutDictionaryId, OpenMode.ForRead);
  36.           Layout newLayout = (Layout)curTrans.GetObject(newID, OpenMode.ForWrite);
  37.           // Клонируем св-ва layout
  38.           newLayout.CopyFrom(templateLayout);
  39.           // Клонируем все объекты с layout
  40.           BlockTableRecord btr = templateTrans.GetObject(templateLayout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
  41.           ObjectIdCollection objs = new ObjectIdCollection();
  42.           foreach (ObjectId ID in btr)
  43.             objs.Add(ID);
  44.           template.WblockCloneObjects(objs, newLayout.BlockTableRecordId, new IdMapping(), DuplicateRecordCloning.Ignore, false);
  45.           curTrans.Commit();
  46.           templateTrans.Commit();
  47.         }
  48.       }
  49.       return newID;
  50.     }

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #4 : 31-03-2020, 16:01:30 »
Извините, вам запрещён просмотр содержимого спойлеров.

Спасибо за пример, но где в нём манипулирование настройками вьюпортов (настройка высоты, ширины, центр вида и тд)?

Я имел ввиду вот такие действия

Код - C# [Выбрать]
  1. namespace Lemieux
  2. {
  3.     public class LMX
  4.     {
  5.         [CommandMethod("TestLayout")]
  6.         public void TestLayout()
  7.         {
  8.             Database db = Application.DocumentManager.MdiActiveDocument.Database;
  9.             using (Transaction tr = db.TransactionManager.StartTransaction())
  10.             {
  11.                 ObjectId layId = LayoutManager.Current.CreateLayout("1");
  12.                 Layout lay = tr.GetObject(layId, OpenMode.ForWrite) as Layout;
  13.                 tr.Commit();
  14.             }
  15.         }
  16.     }
  17. }

И если не переключаться на вновь созданный layout, то в нём будет 0 вьюпортов, но если создать вьюпорты
Код - C# [Выбрать]
  1. using (Viewport acVport = new Viewport())
и добавить их в базу листа, то переключившись на layout вьюпортов будет сразу 4, а не 2.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Создание Layout
« Ответ #5 : 31-03-2020, 16:05:32 »
Спасибо за пример, но где в нём манипулирование настройками вьюпортов (настройка высоты, ширины, центр вида и тд)?
Я ж сразу написал - в шаблоне все уже настроено.

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #6 : 31-03-2020, 16:31:40 »
Спасибо за пример, но где в нём манипулирование настройками вьюпортов (настройка высоты, ширины, центр вида и тд)?
Я ж сразу написал - в шаблоне все уже настроено.
До меня только после моего ответа допёрло  :) Но у меня появилась интересная идея, как обойти проблему, если нельзя добавлять вручную вьюпорты.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #7 : 31-03-2020, 16:59:13 »
После создания layout в его базе 0 вьюпортов, но если туда добавить свои вьюпорты, то после переключения их становится уже 4.
Layout.Initialize тебе в помощь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #8 : 31-03-2020, 17:54:46 »
Layout.Initialize тебе в помощь.
Сначала добавляю свои вьюпорты, а потом инициализирую?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #9 : 31-03-2020, 20:07:40 »
Сначала добавляю свои вьюпорты, а потом инициализирую?
Создаёшь и сразу инициализируешь - появится один основной вьюпорт. Потом можешь уже свои добавлять. И лучше в другой транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #10 : 01-04-2020, 09:35:10 »
Сначала добавляю свои вьюпорты, а потом инициализирую?
Создаёшь и сразу инициализируешь - появится один основной вьюпорт. Потом можешь уже свои добавлять. И лучше в другой транзакции.

Александр, вот так создаю layout

Код - C# [Выбрать]
  1. using (Transaction tr = db.TransactionManager.StartTransaction())
  2. {
  3.     ObjectId layId = LayoutManager.Current.CreateLayout("Lemieux");
  4.     Layout lay = tr.GetObject(layId, OpenMode.ForWrite) as Layout;
  5.     lay.Initialize();
  6.     tr.Commit();
  7. }

Создаётся layout, появляется один вьюпорт, с непонятными значениями, но если нажимать на новосозданную закладку, то ничего не происходит, как чертёж был в пространстве модели так и остаётся. Но если переключится на Layout1(Лист1), а потом переключится на созданный, то всё нормально отображается. Как я понимаю нужно как-то активировать PaperSpace, но я так и не понял как это сделать.
И этот единственный вьюпорт никак не реагирует на установку параметров.

Код - C# [Выбрать]
  1. ObjectIdCollection idCol = lay.GetViewports();
  2. (idCol[0].GetObject(OpenMode.ForWrite) as Viewport).Height = 500;

Так же я пытался добавить вьюпорт на новосозданный layout и получал доступ к PaperSpace вот так

Код - C# [Выбрать]
  1. using (Transaction tr = db.TransactionManager.StartTransaction())
  2. {
  3.     BlockTableRecord pSp = tr.GetObject(btLay[BlockTableRecord.PaperSpace], OpenMode.ForWrite) as BlockTableRecord;
  4.     using (Viewport acVport = new Viewport())
  5.     {
  6.         pSp.AppendEntity(acVport);
  7.         tr.AddNewlyCreatedDBObject(acVport, true);
  8.         tr.Commit();
  9.     }
  10. }
И вьюпорт добавляется к PaperSpace на Layout1(Лист1).
« Последнее редактирование: 02-04-2020, 09:41:41 от Lemieux »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #11 : 01-04-2020, 10:41:09 »
Но если переключится на Layout1(Лист1), а потом переключится на созданный, то всё нормально отображается. Как я понимаю нужно как-то активировать PaperSpace, но я так и не понял как это сделать.
Editor.SwitchToPaperSpace
Editor.SwitchToModelSpace
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #12 : 01-04-2020, 13:02:53 »
Но если переключится на Layout1(Лист1), а потом переключится на созданный, то всё нормально отображается. Как я понимаю нужно как-то активировать PaperSpace, но я так и не понял как это сделать.
Editor.SwitchToPaperSpace
Editor.SwitchToModelSpace

В каком бы месте кода не вызывал "Editor.SwitchToPaperSpace" выдаёт - eInvalidInput.

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #13 : 01-04-2020, 13:21:43 »
ё моё, оказывается даже если получать Layout1, например для того, чтобы скопировать его в свой созданный layout, то в нём так же будет 0 вьюпортов. Как я понимаю нельзя настраивать область печати (вьюпорт) не переключившись на layout. Хотя выполняя на .net код работает в 2 раза быстрее чем на lisp, но хотелось поэкспериментировать с увеличением скорости.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #14 : 01-04-2020, 13:35:30 »
В каком бы месте кода не вызывал "Editor.SwitchToPaperSpace" выдаёт - eInvalidInput.
Это проблема твоего кода.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #15 : 02-04-2020, 09:44:02 »
В каком бы месте кода не вызывал "Editor.SwitchToPaperSpace" выдаёт - eInvalidInput.
Это проблема твоего кода.

А что в нём может быть не так?

Код - C# [Выбрать]
  1. using (Transaction tr = db.TransactionManager.StartTransaction())
  2. {
  3.     ObjectId layId = LayoutManager.Current.CreateLayout("Lemieux");
  4.     Layout lay = tr.GetObject(layId, OpenMode.ForWrite) as Layout;
  5.     lay.Initialize();
  6.     ed.SwitchToPaperSpace
  7.     ed.SwitchToModelSpace
  8.     tr.Commit();
  9. }

Но даже если вызывать переключение в другой транзакции, то всё равно выдаёт eInvalidInput.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #16 : 02-04-2020, 10:32:15 »
Lemieux,
Это вообще на каком языке написано???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #17 : 02-04-2020, 10:41:32 »
Но даже если вызывать переключение в другой транзакции, то всё равно выдаёт eInvalidInput.
Переключение нужно проводить вне транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #18 : 02-04-2020, 11:54:53 »
Это вообще на каком языке написано???
А что не так?

Отмечено как Решение Lemieux 04-04-2020, 01:28:22

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #19 : 02-04-2020, 14:16:57 »
Но если переключится на Layout1(Лист1), а потом переключится на созданный, то всё нормально отображается. Как я понимаю нужно как-то активировать PaperSpace, но я так и не понял как это сделать.
Editor.SwitchToPaperSpace
Editor.SwitchToModelSpace

В каком бы месте кода не вызывал "Editor.SwitchToPaperSpace" выдаёт - eInvalidInput.
Помогло с этой ошибкой - SetSystemVariable("TILEMODE", 0)/.TileMode = false, и транзакция никак не влияла. Но это не выход из ситуации так как уходит время на переключение пространств. Видимо в API нет такой возможности. Жаль конечно, но я много нового узнал.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #20 : 02-04-2020, 14:34:36 »
Это вообще на каком языке написано???
А что не так?
Перечитай тот код, который ты показал. Он у тебя вообще компилируется? Намёк: скобки, точки с запятой.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 379
  • Карма: 21
Re: Создание Layout
« Ответ #21 : 02-04-2020, 15:16:13 »
Это вообще на каком языке написано???
А что не так?
Перечитай тот код, который ты показал. Он у тебя вообще компилируется? Намёк: скобки, точки с запятой.
Александр, ну Вы же понимаете, что это всё спешка и невнимательность и, что ничего не скомпилировалось, если бы я так вставил код в VS.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание Layout
« Ответ #22 : 02-04-2020, 17:25:10 »
Александр, ну Вы же понимаете, что это всё спешка и невнимательность и, что ничего не скомпилировалось, если бы я так вставил код в VS.
Я не буду уточнять в каком случае нужна спешка.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение