При копировании содержимого листа пропускается видовой экран

Автор Тема: При копировании содержимого листа пропускается видовой экран  (Прочитано 10066 раз)

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

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Столкнулся с непонятным (лично мне) поведением автокада.
Задача:
1. Создать новый лист
2. Открыть другой файл
3. Скопировать из первого листа открытого файла все содержимое в созданный лист текущего файла

Первый метод:
Код - C# [Выбрать]
  1. public void Copy(Layout importLayout, Vector3d move)
  2. {
  3.     var curDoc = Application.DocumentManager.CurrentDocument;
  4.     var curDb = curDoc.Database;
  5.  
  6.     using var curT = curDoc.TransactionManager.StartTransaction();
  7.  
  8.     var newLayoutId = CreateLayout(curDb, importLayout);
  9.     var newLayout = newLayoutId.GetObjectAs<Layout>();
  10.  
  11.     using var importLayoutBtr = importLayout.BlockTableRecordId.OpenAs<BlockTableRecord>();
  12.     var importLayoutIds = importLayoutBtr.OfType<ObjectId>().Where(id => id.IsFullyValid()).ToArray();
  13.     if (importLayoutIds.Any())
  14.     {
  15.         var importIds = new ObjectIdCollection(importLayoutIds);
  16.         var map = new IdMapping();
  17.  
  18.         curDb.WblockCloneObjects(
  19.             importIds,
  20.             newLayout.BlockTableRecordId,
  21.             map,
  22.             DuplicateRecordCloning.Ignore,
  23.             false);
  24.     }
  25.  
  26.     curT.Commit();
  27. }

Метод принимает аргументом лист из другого (импортируемого) файла. Сначала создается новый лист, затем происходит копирование содержимого.

Метод создания листа:
Код - C# [Выбрать]
  1. private ObjectId CreateLayout(Database curDb, Layout importLayout)
  2. {
  3.     var layoutName = importLayout.LayoutName;
  4.     var layoutDic = curDb.LayoutDictionaryId.GetObjectAs<DBDictionary>();
  5.     var index = 0;
  6.  
  7.     while (layoutDic.Contains(layoutName))
  8.         layoutName = $"{importLayout.LayoutName}_{++index}";
  9.  
  10.     var newLayoutId = LayoutManager.Current.CreateLayout(layoutName);
  11.     var newLayout = newLayoutId.GetObjectAs<Layout>(true);
  12.     newLayout.CopyFrom(importLayout);
  13.  
  14.     var layoutBtr = newLayout.BlockTableRecordId.GetObjectAs<BlockTableRecord>(true);
  15.     foreach (var vp in layoutBtr.GetObjects<Viewport>(true))
  16.         vp.Erase(true);
  17.  
  18.     return newLayoutId;
  19. }

А теперь к чудесам:
1. Если я закомментирую код с WblockCloneObjects, то получу в итоге новый лист без видового экрана. Что я и делаю в методе CreateLayout
2. Если я раскомментирую код с WblockCloneObjects, то буду получать листы на которых всегда будет находиться видовой экран, который я вроде как удаляю. При этом из импортируемого листа не будет копироваться один видовой экран. Т.е. такое ощущение, что автокад делает так: "О! Я смотрю у тебя тут уже есть ВЭ (хоть ты и удалил его)! Оставим его и не будем копировать новый"

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

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

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Подозреваю, что ты должен закомитить транзакцию, чтобы удаление видовых экранов сработало.
Вот сделал в двух транзакциях:
Извините, вам запрещён просмотр содержимого спойлеров.

Все-равно в результате получаю тот же эффект - один ВЭ из импорта не копируется, а вместо него на листе стандартный ВЭ
« Последнее редактирование: 26-04-2022, 17:51:09 от Александр Пекшев aka Modis »

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Записал видео. Может это даже и не стандартно создаваемый ВЭ, но и не копируемый из листа

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Часть проблемы решается, если созданный лист сделать активным:
Код - C# [Выбрать]
  1. private Layout CreateLayout(Database curDb, Layout importLayout)
  2. {
  3.     using var curT = curDb.TransactionManager.StartTransaction();
  4.  
  5.     var layoutName = importLayout.LayoutName;
  6.     var layoutDic = curDb.LayoutDictionaryId.GetObjectAs<DBDictionary>();
  7.     var index = 0;
  8.  
  9.     while (layoutDic.Contains(layoutName))
  10.         layoutName = $"{importLayout.LayoutName}_{++index}";
  11.  
  12.     var newLayoutId = LayoutManager.Current.CreateLayout(layoutName);
  13.     var newLayout = newLayoutId.GetObjectAs<Layout>(true);
  14.     newLayout.CopyFrom(importLayout);
  15.     LayoutManager.Current.CurrentLayout = newLayout.LayoutName;
  16.     foreach (ObjectId id in newLayout.GetViewports())
  17.         id.GetObjectAs<Viewport>(true).Erase(true);
  18.  
  19.     curT.Commit();
  20.  
  21.     return newLayout;
  22. }

После этого копируются все ВЭ из другого файла.
Но все равно на листе слева внизу образуется какой-то непонятный маленький ВЭ (на видео было видно) с размером 9х12

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Пекшев aka Modis,
Не знаю имеет ли это отношение к этой проблеме, но у тебя в коде одна из стандартных ошибок. Ты открываешь в транзакции объект, потом завершаешь транзакцию и дальше работаешь с этим объектом вне транзакции. Это еще иногда срабатывает с объектами, которые открыты для чтения, но никогда с объектами открытыми для записи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Переделал на всякий случай:
Извините, вам запрещён просмотр содержимого спойлеров.

Но, к сожалению, это не влияет. Все-равно на листе появляется лишний ВЭ

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Взглянул под другим углом - а что если это не фантомный видовой экран и он действительно имеется в импортируемом листе? И оказалось - так и есть.
Правда вот я его на самом листе в упор не вижу и что-то не могу понять почему и как его отличить от других (ну кроме того, что он на слое "0").
Если интересно, файл прикладываю


Оффлайн D_TRex

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Тоже проблема с видовым экраном, не могу получить координаты содержимого
Код - vb.net [Выбрать]
  1.                 Dim acCurDb As Database = acDoc.Database
  2.                 Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  3.                     Dim acLayout As Layout = acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout), OpenMode.ForRead)
  4.                          If (acLayoutMgr.CurrentLayout <> "Model") Then
  5.                         ' acDoc.SendStringToExecute("_.MSPACE" & vbCrLf, True, False, False) ' пробовал активировать, сейчас деактивировано
  6.  
  7.                         Dim wViewports As ObjectIdCollection = acLayout.GetViewports ' этот фрагмент служит для проверки наличия видового экрана и как Вы писали выше их почему то два
  8.                         If wViewports.Count = 0 Then
  9.                             acLayout.UpgradeOpen()
  10.                             acLayout.Initialize()
  11.                             acLayout.DowngradeOpen()
  12.                             wViewports = acLayout.GetViewports
  13.                         End If
  14.  
  15.                         Dim wVP As Viewport = acTrans.GetObject(wViewports(1), OpenMode.ForRead) ' ах да тут задействован wViewports(1), а не wViewports(0), потому что этот даёт те же результаты что и если бы я выполнил (_.MSPACE)
  16.                         rtfTemp.Text = wVP.CenterPoint(0) & " x " & wVP.CenterPoint(1) & vbCrLf & wVP.ViewCenter(0) & " x " & wVP.ViewCenter(1) & vbCrLf & wVP.Height
  17.                         End If
  18.                     acTrans.Abort()
  19.                 End Using
В общем должно быть цент Х (-1314) центр Y (-524) а выдаёт (-372091) и (-311153) пробовал делить, перемножать, вычитать в надежде что есть переводной коэффициент - безуспешно. При этом CenterPoint - это координаты в пространстве листа, а вот это ViewCenter наверное координаты содержимого.

Задачи редактирование содержимого листов, то есть перемещение содержимого для последующего клонирования, в идеале есть ещё вопрос о вращении содержимого, но пока хотя бы ОРТО.


Решил проверить на пустом листе, да проблема в системе координат (как вычислять и изменять не знаю) в общем я работаю одновременно в MEP и Civil и каждый из них видимо по своему интерпретирует координаты. В общем открыл просто "новый документ MEP" и так координаты считались корректно - буду дальше экспериментировать.
« Последнее редактирование: 14-06-2022, 18:51:27 от D_TRex »

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Взглянул под другим углом - а что если это не фантомный видовой экран и он действительно имеется в импортируемом листе? И оказалось - так и есть.
Правда вот я его на самом листе в упор не вижу и что-то не могу понять почему и как его отличить от других (ну кроме того, что он на слое "0").
Если интересно, файл прикладываю


Где-то была вроде раньше тема перебора видовых экранов, дак там тоже что-то было с "нулевым" экраном. Вроде как в справке было написано, что по умолчанию сначала какой то "нулевой" видовой экран идёт, а потом все остальные.

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 626
  • Карма: 161
    • ПГСу Бложик
Где-то была вроде раньше тема перебора видовых экранов, дак там тоже что-то было с "нулевым" экраном.
Link: https://adn-cis.org/forum/index.php?topic=228
и еще для порядка: https://adn-cis.org/forum/index.php?topic=2738