| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Отключение всех видовых экранов в файле

Отключение всех видовых экранов в файле

Ответ
Поиск в этой теме
Непрочитано 24.01.2019, 19:57
Отключение всех видовых экранов в файле
kp+
 
идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,095

Приходится работать с чертежами стороннего разработчика, в которых аффтар (иначе не сказать) сделал в одном листе множество узлов (полтора десятка и более) видовыми экранами довольно тяжелой модели (2D, генплан).
Соответственно, при переключении на лист происходит многократная регенерация модели, Акад (2010, х86) долго думает, а чаще жалуется на нехватку памяти, просит отменить операцию и вообще вешается. Немного спасает autoregenmode 0, но не всегда.

Решил поискать лисп для автоматического отключения всех ВЭ, нашел такое: https://forums.autodesk.com/t5/visua...g/td-p/6390402
Код:
[Выделить все]
 (vl-load-com)
(defun C:viewvis (/ vlist yesno targetvp i)
   (setq i 0)
   (initget "ON OFF")
   (setq yesno (cond ((getkword "\nTurn all viewports on or off? [ON/OFF] <ON>: ")) ("ON")))
   (while (and (/= i (length (layoutlist))) (/= (getvar "dwgname") drawingrefresh))
      (setvar "ctab" (nth i (layoutlist)))
      (setq i (1+ i))
   )
   (setq drawingrefresh (getvar "dwgname"))
   (setq vlist (ssget "x" (list '(0 . "viewport") '(-4 . "/=") '(69 . 1))))
   (while (/= 0 (sslength vlist))
      (setq targetvp (vlax-ename->vla-object (ssname vlist 0)))
      (if (= yesno "ON")
         (vla-display targetvp :vlax-true)
         (vla-display targetvp :vlax-false)
      )
      (ssdel (ssname vlist 0) vlist)
   )
)
Этот лисп нормально работает, но только из того листа, на котором надо погасить все ВЭ, что в моем клиническом случае не подходит

Попробовал пойти своим путем:
Код:
[Выделить все]
 (defun c:kpvpoff (/ ent)
  (setq ent (entnext))
  (while ent
    (if (= (vla-get-ObjectName (vlax-ename->vla-object ent)) "AcDbViewport")
      (if (= (vla-get-ViewportOn (vlax-ename->vla-object ent)) :vlax-true)
	(vla-display  (vlax-ename->vla-object ent) :vlax-false)
      )	
	
    )
    (setq ent (entnext ent))
  )
)
Запускаю из модели (напоминаю, перейти на лист нет возможности), на строке, выделенной красным, выдает ошибку:
Код:
[Выделить все]
Команда: KPVPOFF
; ошибка: Ошибка Automation. Неприменимо
; сброс после ошибки
Инспектор переменных показывает, что переменная в этот момент ent ссылается на включенный видовой экран, со всеми нужными свойствами. И почему метод vla-display применим к ВЭ из пространства "своего" листа, но не из пространства модели - непонятно.

Попробовал без VLA, с dxf-кодами (группа 68 отвечает за включенное состояние ВЭ, если 0, то выкл.)

Код:
[Выделить все]
 (defun c:kpvpoff (/ ent vs_dxf)
  (setq ent (entnext))
  (while ent
    (if (= (vla-get-ObjectName (vlax-ename->vla-object ent)) "AcDbViewport")
      (if (= (vla-get-ViewportOn (vlax-ename->vla-object ent)) :vlax-true)
	(progn
		(setq vs_dxf (entget ent))
	  	(setq vs_dxf (subst (cons 68 0) (assoc 68 vs_dxf) vs_dxf))
	        (entmod vs_dxf)
	        (entupd ent)
        )
      )	
	
    )
    (setq ent (entnext ent))
  )
)
Ошибок нет, но эффекта тоже никакого - ВЭ остаются включены.

Приложить рабочий чертеж не имею возможности, но лисп ведет себя одинаково на любых чертежах, даже на тестовом, где нет ничего, кроме одного ВЭ на одном листе.

Прошу гуру программирования подсказать, что надо добавить в первый или второй лисп, чтобы выключать ВЭ, не переходя на их лист. А если все уже написано - поделитесь ссылкой, пожалуйста.

PS Т.к. чертежи не мои, очевидный вариант создания ВЭ заново в более вменяемой конфигурации или вынесения узлов в пространство листа / в отдельный файл / фтопку рассматриваю в последнюю очередь.
Заменить комп, перейти на версии Винды и Акада х64, добавить памяти - прошу не предлагать

Последний раз редактировалось kp+, 24.01.2019 в 20:37.
Просмотров: 8408
 
Непрочитано 25.01.2019, 16:53
#21
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,679


Цитата:
Сообщение от kp+ Посмотреть сообщение
какие ритуалы проделывает команда сохранения
сохранение закрепляет статус в VP. Повторное открытие восстанивливает status quo, который по ходу нельзя обновить не находясь в нужном лейауте.
koMon вне форума  
 
Непрочитано 25.01.2019, 17:08
#22
maratovich


 
Регистрация: 12.07.2009
г. Самара
Сообщений: 2,481
Отправить сообщение для maratovich с помощью Skype™


Цитата:
Сообщение от doctorraz Посмотреть сообщение
т.е. это АК2018 теперь так работает
На работе 2018 без проблем.
Дома 2018 eng - глюки.
Походу от сборки зависит.
__________________
Вопрос : Где находится Тургай ? Ответ : Между Парагваем и Уругваем.....
maratovich вне форума  
 
Непрочитано 25.01.2019, 17:21
#23
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


2018 нет.
Автокад 2019.1.2 x64 работает без проблем
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 25.01.2019, 18:28
#24
doctorraz

электрик
 
Регистрация: 19.02.2010
Волгоград
Сообщений: 2,295
Отправить сообщение для doctorraz с помощью Skype™


Цитата:
Сообщение от maratovich Посмотреть сообщение
На работе 2018 без проблем.
Дома 2018 eng - глюки.
тут возможно от видимости ленты и положения луны в сатурне
с 2018 похоже косяк, но других установленных у мну нет, а иные ставить лениво..
вроде разобрались.. было весело
__________________
Мастерская СПДС
doctorraz вне форума  
 
Непрочитано 25.01.2019, 18:34
#25
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,835


Попытка решения на C#: http://adn-cis.org/forum/index.php?t...36660#msg36660
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.01.2019, 18:53
#26
doctorraz

электрик
 
Регистрация: 19.02.2010
Волгоград
Сообщений: 2,295
Отправить сообщение для doctorraz с помощью Skype™


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Попытка решения на C#:
чтото мне подсказывает, что коль в Ак 2016 и 2019 вышеприведенные лиспы работают, а в АК 2018 нет.. проблема не в коде..
то что видовых экранов больше на количество листов уже поняли
вангую этот код на ак2018 ру даст тот же результат

----- добавлено через ~2 мин. -----
в принципе и на vb выбрать селсетом, а потом проходом по коллекции (исключая вэ листа) должно получиться, но не в ак2018((
__________________
Мастерская СПДС
doctorraz вне форума  
 
Непрочитано 25.01.2019, 19:18
#27
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Попытка решения на C#: http://adn-cis.org/forum/index.php?t...36660#msg36660
если итоговый код запустить на листе, то что будет при попытке выключить первый viewport c настройками листа?
Сергей812 вне форума  
 
Непрочитано 25.01.2019, 19:31
#28
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,835


Ну, свой код я как раз на 2018 и рисовал...
Цитата:
Сообщение от Сергей812 Посмотреть сообщение
если итоговый код запустить на листе
А я откуда знаю? У меня в C# познаний хватает только понять, что это именно C#, а не С++
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.01.2019, 19:37
#29
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
А я откуда знаю? У меня в C# познаний хватает только понять, что это именно C#, а не С++
Ну я там просто не зареган, а автор той ветки сюда смотрит явно
Сергей812 вне форума  
 
Непрочитано 25.01.2019, 19:44
#30
doctorraz

электрик
 
Регистрация: 19.02.2010
Волгоград
Сообщений: 2,295
Отправить сообщение для doctorraz с помощью Skype™


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
если итоговый код запустить на листе, то что будет при попытке выключить первый viewport c настройками листа?
каду это не нравится.. падает
__________________
Мастерская СПДС
doctorraz вне форума  
 
Непрочитано 25.01.2019, 20:08
#31
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Цитата:
Сообщение от doctorraz Посмотреть сообщение
каду это не нравится.. падает
угу.. акад нервно реагирует на попытки модификации ВЭ самого листа.

Offtop: Поэтому возможные варианты (по простоте реализации):

1. Добавить флаг
Код:
[Выделить все]
[Rtm.CommandMethod("TurnedOffAllViewport", Rtm.Modal | Rtm.NoPaperSpace)]
для запрета вызова команды из пространства листа.
2. Сохранить значение TileMode и принудительно переключиться в пространство модели на время обработки.
3. При значении системной переменной TileMode=0 получить ссылку на менеджер листов
Код:
[Выделить все]
LayoutManager lLayoutManager = LayoutManager.Current;
и в цикле проверять - не совпадает ли обрабатываемый лист по имени с lLayoutManager.CurrentLayout. При совпадении корректировать границы цикла для пропуска первого ВЭ.

Последний раз редактировалось Сергей812, 26.01.2019 в 00:39. Причина: Неверно
Сергей812 вне форума  
 
Непрочитано 25.01.2019, 20:35
#32
doctorraz

электрик
 
Регистрация: 19.02.2010
Волгоград
Сообщений: 2,295
Отправить сообщение для doctorraz с помощью Skype™


выше VVA лисп дал, там все чотко..
__________________
Мастерская СПДС
doctorraz вне форума  
 
Непрочитано 25.01.2019, 20:45
#33
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Сергей812, простите, но Вы ерунду написали. Приведенному по ссылке коду пофигу откуда его запускают, все ВЭ в любом случае будут выключены.
Даже если в момент запуска кода был выполнен вход в ВЭ.
Тестировал Акад 2017х64 Win7
update:
ХМ... там пары строчек не хватает... и из-за этих строчек код на 2016 и ниже нормально работать не будет... в любом случае коду пофигу откуда его стартуют

Последний раз редактировалось Boxa, 25.01.2019 в 21:18.
Boxa вне форума  
 
Непрочитано 25.01.2019, 21:09
#34
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Цитата:
Сообщение от Boxa Посмотреть сообщение
Сергей812, простите, но Вы ерунду написали. Приведенному по ссылке коду пофигу откуда его запускают, все ВЭ в любом случае будут выключены.
Даже если в момент запуска кода был выполнен вход в ВЭ.
Тестировал Акад 2017х64 Win7
Акад 2018х64 Win7
При попытке запуске вашего кода как из пространства модели, так из пространства листа - на строчке "vp.On = false;" вылетает исключение "eNotInPaperspace". А в других версиях акада и лисп работает, судя по ветке.
Сергей812 вне форума  
 
Непрочитано 26.01.2019, 00:52
#35
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Цитата:
Сообщение от Boxa Посмотреть сообщение
Сергей812, простите, но Вы ерунду написали.
Действительно, немного куда то не туда занесло - приношу свои извинения) Самое парадоксальное, что ваш код заработал и на 2018 с какой то попытки - но не совсем корректно: ВЭ отключает - а содержимое продолжает стабильно показывать на всех вкладках листов, что были неактивны. И регенерация не помогает. Мой вариант кода вроде стабильнее работает:


Код:
[Выделить все]
// Autocad
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;


/// <summary>
/// Включение / выключение показа содержимого видовых экранов
/// </summary>
namespace SetVisibleContentVPorts
{
    public class CommandsClass
    {
        /// <summary>
        /// Вспомогательная функция установки статуса видимости содержимого ВЭ
        /// </summary>
        /// <param name="aOnState">Статус видимости содержимого ВЭ</param>
        private void SetVPState(bool aOnState)
        {
            // Получаем текущий документ и его БД
            Document lAcadDoc = Application.DocumentManager.MdiActiveDocument;
            Database lAcadDb = lAcadDoc.Database;
            // Сохраняем предыдущую рабочую БД
            Database lOldWorkDatabase = HostApplicationServices.WorkingDatabase;
            // И задаем БД нашего чертежа
            HostApplicationServices.WorkingDatabase = lAcadDb;
            // Общий обработчик ошибок
            try
            {
                // Открываем транзакцию
                using (Transaction lAcadTr = lAcadDb.TransactionManager.StartTransaction())
                {
                    // Получаем таблицу пространства модели
                    BlockTable lBlockTable = lAcadTr.GetObject(
                        lAcadDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    BlockTableRecord lModelSpace = lAcadTr.GetObject(
                        lBlockTable[BlockTableRecord.ModelSpace],
                            OpenMode.ForRead) as BlockTableRecord;
                    // Получаем словарь листов (включая модель)
                    DBDictionary lDict = lAcadTr.GetObject(
                        lAcadDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                    // В цикле по полученному словарю
                    foreach (DBDictionaryEntry lEntry in lDict)
                    {
                        // Если это не пространство модели
                        if (!lEntry.Value.Equals(lModelSpace.LayoutId))
                        {
                            // Получаем лист
                            Layout lLayout = lAcadTr.GetObject(
                                lEntry.Value, OpenMode.ForRead) as Layout;
                            // Получаем коллекцию видовых экранов
                            ObjectIdCollection lColVPIds = lLayout.GetViewports();
                            // Если у листа нет ни одного ВЭ - требуется инициализировать
                            if (lColVPIds.Count == 0)
                            {
                                lLayout.UpgradeOpen();
                                lLayout.Initialize();
                                lLayout.DowngradeOpen();
                                lColVPIds = lLayout.GetViewports();
                            }
                            // Если на листе есть ВЭ
                            if (lColVPIds.Count > 1)
                            {
                                // Начиная со второго ВЭ
                                for (int i = 1; i < lColVPIds.Count; i++)
                                {
                                    // Получаем ВЭ
                                    Viewport lViewport = lAcadTr.GetObject(
                                        lColVPIds[i], OpenMode.ForWrite) as Viewport;
                                    // Ставим статус видимости содержимого
                                    lViewport.On = aOnState;
                                    // Обновляем ВЭ
                                    lViewport.UpdateDisplay();
                                }
                            }
                        }
                    }
                    // Подтверждаем транзакцию
                    lAcadTr.Commit();
                }
            }
            catch (System.Exception ex)
            {
                // Сообщение об ошибке
                lAcadDoc.Editor.WriteMessage("\nПроизошла ошибка: [{0}]", ex.Message);
            }
            finally
            {
                // Восстанавливаем предыдущую рабочую БД
                HostApplicationServices.WorkingDatabase = lOldWorkDatabase;
            }
        }


        /// <summary>
        /// Команда включения всех видовых экранов листов
        /// </summary>
        [CommandMethod("VP_On", CommandFlags.Modal)]
        public void VP_On()
        {
            SetVPState(true);
        }


        /// <summary>
        /// Команда выключения всех видовых экранов листов
        /// </summary>
        [CommandMethod("VP_Off", CommandFlags.Modal)]
        public void VP_Off()
        {
            SetVPState(false);
        }

    }
}


Ну и прикрепляю сборку под 2018х64 для теста. Не забывайте в свойствах скаченного файла снимать "Файл был получен с другого компьютера..." - чтобы акад при загрузке не ругался.
Команды: VP_On и VP_Off - включение/отключение показа содержимого ВЭ.

----- добавлено через ~1 ч. -----
2018 работает очень своебразно и в .Net:
1. Если после открытие чертежа не переключишь хоть раз между лейаутами для регенерации (TileMode не прокатывает) - стабильно выдает исключение "eNotInPaperspace".
2. Визуально результат выключения ВЭ 100% виден при случае активного листа, как и на лиспе. На неактивных - результат или при повторном вызове команды, или при переоткрывании чертежа. Хотя порою и на неактивных листах отображается выключение ВЭ нормально - связи никакой не заметил.
3. А вот включает ВЭ на всех листах спокойно, как и выше писали - в СПДС.
4. И насколько заметил, при изменении количества ВЭ на листах начинает игнорировать команды моей надстройки на неактивных листах вплоть до переоткрытия чертежа.
Вложения
Тип файла: zip SetVisibleContentVPorts.zip (2.7 Кб, 13 просмотров)
Сергей812 вне форума  
 
Непрочитано 26.01.2019, 09:22
#36
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Я же написал, что там пары строчек не хватает...
"eNotInPaperspace" лечится просто оберткой в try (на 2017 эта ошибка так же бывает... на разных компах)
Для того, что бы визуально был виден результат для неактивных листов, нужно принудительно обновить графику каждого ВЭ (acdbEntUpd или что то подобное)

В любом случае развивать эту тему в рамках раздела Lisp не очень хорошо, да и обсуждать там по большому счету нечего, т.к. приведенный по ссылке код, не более чем набросок, написанный просто для понимания и отработки основной идеи и понятно, что там много чего не хватает для полноценного приложения.

Последний раз редактировалось Boxa, 26.01.2019 в 09:30.
Boxa вне форума  
 
Непрочитано 26.01.2019, 10:37
#37
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Цитата:
Сообщение от Boxa Посмотреть сообщение
"eNotInPaperspace" лечится просто оберткой в try (на 2017 эта ошибка так же бывает... на разных компах)
и толку - пока не переключишь вкладки для регенерации, так и будет:
Цитата:
Команда: VP_ON
Произошла ошибка: [eNotInPaperspace]
Команда: VP_ON
Произошла ошибка: [eNotInPaperspace]
Команда: VP_ON
Произошла ошибка: [eNotInPaperspace]
Команда: VP_ON
Произошла ошибка: [eNotInPaperspace]
т.е. оберткой в обработчик просто неработающий код получите и все.


Цитата:
Сообщение от Boxa Посмотреть сообщение
нужно принудительно обновить графику каждого ВЭ (acdbEntUpd или что то подобное)
Ну так UpdateDisplay(); - This function updates the onscreen display to reflect any changes made to the viewport's view parameters (Эта функция обновляет экранный дисплей, отражая любые изменения параметров представления видового экрана.). Но здесь есть подводный камень - is not onscreen, then this function does nothing (не находится на экране, то эта функция ничего не делает). Поэтому только активный лист и обновляет.
Сергей812 вне форума  
 
Непрочитано 26.01.2019, 13:10
#38
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Сергей812, есть разница между acdbEntUpd и UpdateDisplay, а по поводу eNotInPaperspace, ничего сказать не могу, на 2017 такую ошибку удалось сделать, но все решилось через try, после обертки ошибка перестала влиять на выполнение и ВЭ выключались.

ЗЫ. ИМХО, обсуждать в ветке LISP код на C#, к тому же размещенный не тут - неуважение к автору топика. Если есть желание продолжить копаться, рекомендую зарегистрироваться на том сайте и продолжить дискуссию там.
Boxa вне форума  
 
Непрочитано 27.01.2019, 11:33
#39
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,039


Offtop:
Цитата:
Сообщение от Boxa Посмотреть сообщение
к тому же размещенный не тут. Если есть желание продолжить копаться, рекомендую зарегистрироваться на том сайте и продолжить дискуссию там.
Ну свой под катом выложил, только сам 2018 недоработан и не во всех локальных апдейтах подправлен, похоже) Понимаю, здесь плюсики в карму не идут) И посмотрите в отладчике на строчку кода " if (item.Key != Db.BlockTableRecord.ModelSpace)" - будет ли вообще когданибудь работать это условие..
Сергей812 вне форума  
 
Непрочитано 27.01.2019, 18:02
#40
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Offtop:
Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Понимаю, здесь плюсики в карму не идут
я мальчик взрослый, меня эта фигня с плюсиками, ачивками и прочей фигней мало интересует.
Цитата:
Сообщение от Сергей812 Посмотреть сообщение
И посмотрите в отладчике на строчку кода " if (item.Key != Db.BlockTableRecord.ModelSpace)" - будет ли вообще когданибудь работать это условие..
Доберусь до компа со студией и посмотрю.
Boxa вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Отключение всех видовых экранов в файле

Размещение рекламы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Создание листов и видовых экранов на них Andrey_13 Готовые программы 423 03.04.2024 21:27
Как выключить "Показ блокированного/Display locked" на всех видовых экранах на всех листах сразу? UnAtom AutoCAD 2 25.08.2017 16:38
Лисп для блокировки видовых экранов posetitel LISP 5 28.04.2017 09:09
AutoCAD 2011. Проблема с заданием масштабов видовых экранов. Demyan AutoCAD 1 28.11.2010 10:42
Как слой включить сразу во всех видовых экранах ilka_t AutoCAD 4 26.04.2004 11:20