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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Как быстро преобразовать в отрезки десятки тысяч полилиний при помощи LISP

Как быстро преобразовать в отрезки десятки тысяч полилиний при помощи LISP

Ответ
Поиск в этой теме
Непрочитано 19.07.2014, 14:44 #1
Как быстро преобразовать в отрезки десятки тысяч полилиний при помощи LISP
Влад-и-мир
 
Регистрация: 19.07.2014
Сообщений: 9

Имеется чертеж в котором надо преобразовать в отрезки несколько десятков тысяч полилиний.
Единственный язык программирования, которым владею - LISP.
Единственный способ, который знаю - (command"_explode")
Проблема в том, что в автокаде команду можно применить сразу к набору данных, содержащих полилинии, и тогда она работает моментально, а в программе так не получается, только в цикле по одному примитиву. В результате процесс затягивается до получаса..
Чертежи формируются в сторонних организациях. Выполнить преобразование над набором полилиний вручную нежелательно, т.к. получению этого набора предшествуют программные действия, и после преобразования программа продолжает работу.
Просмотров: 5341
 
Непрочитано 19.07.2014, 16:56
#2
nolte

спринклеры, сантехника
 
Регистрация: 26.01.2010
Сообщений: 188
Отправить сообщение для nolte с помощью Skype™


Влад-и-мир, лиспа вполне достаточно для этой задачи
Код:
[Выделить все]
 
(defun c:55 ()
(vl-load-com)
(mapcar '(lambda(a)(vla-explode a))(mapcar 'vlax-ename->vla-object(l-conv-set-to-lst(ssget "_X" (list(cons 0 "*Polyline"))))))
)
(defun L-conv-set-to-lst (n / i lst)
(repeat (setq i (sslength n))
	(setq lst (cons (ssname n (setq i (1- i))) lst))
)
)
__________________
Знание лисп: со справочником Н. Полещука
nolte вне форума  
 
Непрочитано 19.07.2014, 18:02
#3
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


nolte, Вроде русским языком написали что ПО ОДНОМУ - ДОООЛГО
gomer вне форума  
 
Непрочитано 19.07.2014, 18:35
#4
VVA

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


Цитата:
Сообщение от Влад-и-мир Посмотреть сообщение
а в программе так не получается, только в цикле по одному примитиву. В результате процесс затягивается до получаса..
Почитай этот пост
Цитата:
Обнаружился еще один интересный нюанс использования QAFLAGS. Это касается использования команды _EXLODE при вызове из Lisp-функций Lisp-скриптов. Описание использования команды однозначно говорит нам, что (цитата из справки по команде _EXPLODE (РАСЧЛЕНИТЬ))
Цитата:
Примечание:Если используется какой-либо пакет или функция ObjectARX®, то за один раз можно выполнить расчленение только одного объекта.
Цитата:
Note: If you're using a script or an ObjectARX® function, you can explode only one object at a time.
Вариант с использованием QAFLAGS (на примере блоков)
Код:
[Выделить все]
(defun c:440 ( / *error* ss qf )
 ;; © Lee Mac 2010
  (defun *error* ( msg )
    (and qf (setvar 'QAFLAGS qf))
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ)
  )
  (if (setq ss (ssget "_X" '((0 . "INSERT"))))
    (progn
      (setq qf (getvar 'QAFLAGS))
      (setvar 'QAFLAGS 5)
      (command "_.explode" ss "")
      (setvar 'QAFLAGS qf)
    )
  )
  (princ)
)
А так же тему insert and explode block lisp Help обращая внимание на использование функции (initcommandversion)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 20.07.2014, 00:23
#5
nolte

спринклеры, сантехника
 
Регистрация: 26.01.2010
Сообщений: 188
Отправить сообщение для nolte с помощью Skype™


gomer, прав. видел все букоуки но не сумел прочитать слова.
__________________
Знание лисп: со справочником Н. Полещука
nolte вне форума  
 
Непрочитано 20.07.2014, 00:34
#6
Dakar


 
Регистрация: 05.07.2010
Сообщений: 659


мммммм, а не проще быстрым выбором выбрать полилинии и затем их взорвать. Без лиспа. При желании написать лисп автоматизирующий данные действия.
Dakar вне форума  
 
Автор темы   Непрочитано 20.07.2014, 10:53
#7
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Цитата:
Сообщение от Dakar Посмотреть сообщение
мммммм, а не проще быстрым выбором выбрать полилинии и затем их взорвать. Без лиспа. При желании написать лисп автоматизирующий данные действия.
Я писал, в программе идет предварительная обработка, потом взрываются полилинии, потом идет заключительная обработка. Сам взрыв полилиний без лиспа может сопровождается идиотским вопросом Автокада, который будет пугать пользователей - об отказе от порядка следования объектов для ускорения работы (он именно про полилинии), причем у меня этот вопрос Автокад почему-то сейчас больше не спрашивает, но вначале точно спрашивал. Т.е. вместо одного вызова пришлось бы делать три, и писать инструкцию по воросу, в которой предупреждать, что он может отсутствовать.. В первой части идет диалог, так что загнать в один пункт меню не получится.

----- добавлено через ~51 мин. -----
Цитата:
Сообщение от VVA Посмотреть сообщение
Почитай этот пост
Не хочется связывться с недокументированными переменными, хотя, возможно, придется. В целом, надежда появилась.. Спасибо !
Все-таки пишут, что переменная введена еще на R11, кроме того, она очень широко описана на форумах, хотя во всех описаниях значений битов про ее влияние на explode не пишется. Но отмахнуться от нее уже, надеюсь, Автодеску не удасться. Кстати на ссылке http://mistressofthedorkness.blogspo...r-autocad.html дано значение еще одного бита:
bit 7 (128) : accepts "screen picks" (point lists) via (command) function.
Признаюсь, машинные переводчики мне не помогли понять этот текст.
Я проверю ваш код, как только поставлю еще A2014 и A2002 (сам работаю на A2008). С вертикальными решениями связываться лень, мне кажется, что ядро обычного Автокада туда переносится без изменений, речь идет просто о дополнительных расширениях и общие соглашения должны соблюдаться везде. Т.е. возможно действие QAFLAGS там расширено, но врядли сужено.
Как только все проверю - отпишусь.
Влад-и-мир вне форума  
 
Непрочитано 20.07.2014, 13:26
#8
VVA

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


Я бы не игнорировал и initcommandversion. Правда, судя по описанию, появилось это в 2009
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 20.07.2014, 14:19
#9
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Проверка прошла успешно. Все теперь летает! Единственный нюанс - появлялось описанное ранее сообщение (вернее диалоговое окно):
Эта операция может занять длительное время.
Чтобы существенно повысить производительность, система может игнорировать порядок прорисовки.
Игнорировать порядок прорисовки для этой операции?
Да Нет

При ответе Нет прирост скорости невооруженным взглядом не заметен.
На небольших тестовых примерах этого окна не было, а на реальном файле - есть.
Работе программы оно на A2008 не помешало. Теперь буду тестировать на 2002 и 2014 Автокадах. Сразу по получению результата отпишусь.

----- добавлено через ~4 мин. -----
Цитата:
Сообщение от VVA Посмотреть сообщение
Я бы не игнорировал и initcommandversion. Правда, судя по описанию, появилось это в 2009
А я вынужден проигнорировать, т.к. для меня А2008 весьма актуален.
Влад-и-мир вне форума  
 
Непрочитано 20.07.2014, 15:21
#10
VVA

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


Можно попробовать подавить сообщение с помощью переменной NOMUTT
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 20.07.2014, 20:14
#11
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Попробую и отпишусь. Но там Диалоговое окно, а не сообщение.

----- добавлено через ~4 ч. -----
Цитата:
Сообщение от VVA Посмотреть сообщение
Можно попробовать подавить сообщение с помощью переменной NOMUTT
Попробовал. Давит сообщения исключительно, вплоть до запроса Автокада Команда: и всех запросов программы, так что пришлось ставить непосредственно перед _Explode и сразу же после нее обнулять. Увы. На диалоговое окно она не способна влиять (А2008).
Влад-и-мир вне форума  
 
Непрочитано 21.07.2014, 10:07
#12
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Можно обнулять переменную draworderctl - сообщения не будет. Но тогда не будет сохраняться исходный порядок отрисовки примтивов. Как-то я использовал такой способ как раз для подавления этого сообщения, а потом, после обработки, запускал команду _texttofront.
__________________
Толковый выбор приходит с опытом, а к нему приводит выбор бестолковый. (The Mechanic)
Do$ вне форума  
 
Автор темы   Непрочитано 21.07.2014, 12:31
#13
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Цитата:
Сообщение от Do$ Посмотреть сообщение
Можно обнулять переменную draworderctl - сообщения не будет. Но тогда не будет сохраняться исходный порядок отрисовки примтивов.
Выигрыш скорости получается как раз только в таком режиме. Неприятностей от него никаких нет. Если вновь образованные линии станут последними в чертеже - будет даже лучше!
Интересно, м.б она тогда согласится без Qaflags одним explode группу примитивов обрабатывать. Результат отпишу.
Влад-и-мир вне форума  
 
Непрочитано 21.07.2014, 12:57
#14
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Цитата:
Сообщение от Влад-и-мир Посмотреть сообщение
Если вновь образованные линии станут последними в чертеже
Как раз таки они вылезают на передний план.
__________________
Толковый выбор приходит с опытом, а к нему приводит выбор бестолковый. (The Mechanic)
Do$ вне форума  
 
Автор темы   Непрочитано 21.07.2014, 18:35
#15
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Цитата:
Сообщение от Do$ Посмотреть сообщение
Можно обнулять переменную draworderctl
В А2002 ее нет.. Нет и диалогового окна.. Т.е. придется проверять наличие переменной. Например через getvar - все равно старое значение возвращать после explode ...
В общем - на А2008 диалоговое окно устранилось, т.е. пользователям нагрузку от непонятного запроса удалось снять при помощи обнуления переменной draworderctl. На А2002 проверка должна исключать установку переменной; проверю и выставлю код общий для всех Автокадов, начиная с А2002 (без проверки на А2015 - его под рукой нет). Проблема решена с помощью уважаемых VVA и Do$. Окончательный отчет и текст фрагмента программы - за мной!
Влад-и-мир вне форума  
 
Непрочитано 21.07.2014, 19:17
#16
VVA

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


Цитата:
Сообщение от Влад-и-мир Посмотреть сообщение
Т.е. придется проверять наличие переменной.
Цитата:
Сообщение от Влад-и-мир Посмотреть сообщение
На А2002 проверка должна исключать установку переменной
У меня так работает для всех Автокадов
Код:
[Выделить все]
(if (getvar "ROLLOVERTIPS")(setvar "ROLLOVERTIPS" 0)) ;_Подсказки ролловеров
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 21.07.2014, 19:53
#17
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Итак, промежуточный итог - код:
(setQ nabor (ssget "X"(list(cons 0 “*POLYLINE”))))
(If nabor(progn
(If (setq d-order(getVar "draworderctl"))(setVar "draworderctl" 0));if
(setVar "qaflags"5)
(command "_explode"nabor "")
(setVar "qaflags"0)
(If d-order(setVar "draworderctl" d-order));if
);progn
);if

Работает и в А2002 и в А2008. Про А2014 допишу. Применение кода сократило общее время работы программы в ~4 раза.
На А2002 программа работает почти в 2 раза быстрее чем на А2008.
Совпадает с вариантом VVA, но возвращает начальное значение draworderctl, если переменная существует.

Последний раз редактировалось Влад-и-мир, 21.07.2014 в 20:06.
Влад-и-мир вне форума  
 
Непрочитано 21.07.2014, 20:35
#18
Кулик Алексей aka kpblc
Moderator

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


regenmode по ходу дела еще в 0 (с последующей принудительной перерисовкой) может еще ускорить работу.
А вообще говоря, нередко ActiveX (в отличие от командных методов или entmake[x]), в этом отношении может быть удобнее. Можешь проверить:
Свой код:
Код:
[Выделить все]
 (defun c:vlad (/ nabor d-order time)
  (setq nabor (ssget "_X" (list (cons 0 "*POLYLINE"))))
  (if nabor
    (progn
      (if (setq d-order (getvar "draworderctl"))
        (setvar "draworderctl" 0)
        ) ;if
      (setvar "qaflags" 5)
      (setq time (getvar "cdate"))
      (command "_explode" nabor "")
      (setvar "qaflags" 0)
      (if d-order
        (setvar "draworderctl" d-order)
        ) ;_ end of if
      (princ (strcat "\nExecuting time : " (rtos (* 1e6 (- (getvar "cdate") time)) 2 14) " sec"))
      ) ;_ end of progn
    ) ;_ end of if
  (princ)
  ) ;_ end of defun
И мой вариант:
Код:
[Выделить все]
 (vl-load-com)

(defun c:441 (/ adoc selset time)
  (if (= (type (setq selset (vl-catch-all-apply
                              (function
                                (lambda ()
                                  (ssget "_:L" '((0 . "*POLYLINE")))
                                  ) ;_ end of lambda
                                ) ;_ end of function
                              ) ;_ end of vl-catch-all-apply
                     ) ;_ end of setq
               ) ;_ end of type
         'pickset
         ) ;_ end of =
    (progn
      (setq time (getvar "cdate"))
      (foreach ent (mapcar
                     (function vlax-ename->vla-object)
                     ((lambda (/ tab item)
                        (repeat (setq tab  nil
                                      item (sslength selset)
                                      ) ;_ end setq
                          (setq tab (cons (ssname selset (setq item (1- item))) tab))
                          ) ;_ end of repeat
                        ) ;_ end of lambda
                      )
                     ) ;_ end of mapcar
        (if (vlax-method-applicable-p ent 'explode)
          (progn
            (vla-explode ent)
            (vla-erase ent)
            ) ;_ end of progn
          (vla-put-color ent 1)
          ) ;_ end of if
        ) ;_ end of foreach
      (princ (strcat "\nExecuting time : " (rtos (* 1e6 (- (getvar "cdate") time)) 2 14) " sec."))
      ) ;_ end of progn
    ) ;_ end of if
  (princ)
  ) ;_ end of defun
----- добавлено через 22 сек. -----
regenmode специально не менял
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 22.07.2014, 11:50
#19
Влад-и-мир


 
Регистрация: 19.07.2014
Сообщений: 9


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
И мой вариант:
Твой вариант просит выбрать объекты и при пустом ответе ничего не делает. М.б. дело в (ssget "_:L" '((0 . "*POLYLINE"))) ?

----- добавлено через ~7 мин. -----
Прошу высказаться о надежности использования недокументированной системной переменной QAFLAGS:
- С одной стороны она введена еще в прошлом веке и довольно широко рекомендуется на различных форумах для решения моей проблемы, что предполагает какую-то ответственность Автодеск де-факто;
- С другой стороны - недокументированность предполагает отсутствие ответственности де-юре.
Влад-и-мир вне форума  
 
Непрочитано 22.07.2014, 12:26
#20
Кулик Алексей aka kpblc
Moderator

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


Правильно. Потому что далеко не факт что надо "разбивать" все и вся. Хочешь - замени _:L на _X, и добавь обработку блокированных и замороженных слоев.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Как быстро преобразовать в отрезки десятки тысяч полилиний при помощи LISP

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Какой язык перспективен для инженера-конструктора с условием The_Mercy_Seat Программирование 705 17.03.2021 14:19