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

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

LISP. Выделение блоков с динамическими свойствами

Ответ
Поиск в этой теме
Непрочитано 15.02.2012, 14:51 #1
LISP. Выделение блоков с динамическими свойствами
Composter
 
Отопление и вентиляция
 
Москва
Регистрация: 31.10.2008
Сообщений: 445

здравствуйте, форумчане.подскажите можно ли оптимизировать код для выделения блоков с динамическими свойствами.мне пришло на ум только вот это
Код:
[Выделить все]
 (setq ss1(mapcar '(lambda (obj)(vlax-ename->vla-object obj))(vl-remove-if-not '(lambda(x)	(equal (vla-get-IsDynamicBlock  (vlax-ename->vla-object x)):vlax-true))(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget '((0 . "INSERT")))))))))
когда на чертеже много блоков, компутер задумывается ненадолго
Просмотров: 3409
 
Непрочитано 15.02.2012, 17:44
#2
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


как выбрать динамические блоки по состоянию видимости? Оно?
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 15.02.2012, 20:22
#3
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 811


Цитата:
Сообщение от Composter Посмотреть сообщение
когда на чертеже много блоков, компутер задумывается ненадолго
попробуй может методами ActiveX будет шустрее выбирать:
Код:
[Выделить все]
 (defun C:demo(/ adoc obj_list pfset )
(setq adoc (vla-get-activedocument (vlax-get-acad-object))
      pfset (vla-get-pickfirstselectionset adoc)
      )
(vl-catch-all-apply 'vlax-invoke (list pfset 'clear))

  (vla-select pfset acselectionsetall nil nil
  (vlax-safearray-fill
    (vlax-make-safearray vlax-vbinteger '(0 . 1))
    (list 0 2));<--dxf codes
  (vlax-safearray-fill
   (vlax-make-safearray vlax-vbvariant '(0 . 1))
   (list "insert" "*,`*U*");<--dxf values
  )
 )
(princ (strcat "\n\t---\tSelected: " (vl-princ-to-string (vlax-get pfset 'count))))
  (vlax-for obj pfset
    (if (equal :vlax-true (vla-get-IsDynamicBlock obj))
	     (setq obj_list (cons obj obj_list))))
  
  (princ (strcat "\n\t---\tDynamic block count: " (itoa (length obj_list))))
  (princ)
  )
(vl-load-com)
(princ)
~'o'~
Олег (jr.) вне форума  
 
Непрочитано 15.02.2012, 23:05
#4
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Ну как минимум убрать 2-х кратное повторение преобразования перевода ename->vla (переведи а потом фильтруй). Можно конечно и вобще в одну операцию это делать, но выйгрыш в данном случае будет не большой.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 15.02.2012, 23:17
#5
Composter

Отопление и вентиляция
 
Регистрация: 31.10.2008
Москва
Сообщений: 445


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Ну как минимум убрать 2-х кратное повторение преобразования перевода ename->vla (переведи а потом фильтруй). Можно конечно и вобще в одну операцию это делать, но выйгрыш в данном случае будет не большой.
я это понимаю, но как это сделать в одной операции не приходит в голову.
Composter вне форума  
 
Непрочитано 15.02.2012, 23:28
#6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Код:
[Выделить все]
 (vl-remove-if-not
  '(lambda(x) (equal (vla-get-IsDynamicBlock  x):vlax-true))
   (mapcar
     'vlax-ename->vla-object
     (vl-remove-if 'listp
                   (mapcar 'cadr (ssnamex (ssget '((0 . "INSERT"))))))))
p.s. здесь мы вначале все переводим в vla - а потом по всем "пробегаем" фильтром, можно это делать и в одну операцию - но код будет либо рекурсивный (а если блоков много - как видимо в твоем случае - то закончиться переполнением стека автолиспа), либо "некрасивый" с моей точки зрения, но самое главное из-за постоянного присваивания (второй случай) код будет вряд-ли более быстрым (тут хоть и двухкратная "пробежка" по списку - но зато 2 встроенными функциями - более производительными чем "свои").
з.з.ы пяток процентов к скорости можно добавить заменив ' на function.
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 15.02.2012 в 23:41.
Дима_ вне форума  
 
Автор темы   Непрочитано 15.02.2012, 23:33
#7
Composter

Отопление и вентиляция
 
Регистрация: 31.10.2008
Москва
Сообщений: 445


я это пробовал,это наоборот замедлит лисп, в моем варианте о вначале выкидывает динамические блоки а потом переводит в vla-object, а в этом варианте наоборот
Composter вне форума  
 
Непрочитано 15.02.2012, 23:43
#8
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


пробуй еще раз - ты когда проверяешь что есть дин. блок и так ВСЕ переводишь в vla.
з.ы. сколько у тебя вхождений блоков?
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 16.02.2012, 10:46
#9
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


А не является ли признаком дин. блока наличие DXF 360 - Hard-owner ID/handle to owner dictionary. Тогда может быть так:
Код:
[Выделить все]
 (setq x00 (ssget "_X" '((0 . "INSERT")))
      x01 -1
      x02 (list))
(repeat (sslength x00) (and (assoc 360 (setq x03 (entget (ssname x00 (setq x01 (1+ x01)))))) (setq x02 (append x02 (list (cdr (assoc -1 x03)))))))
(setq x00 nil)
ciril вне форума  
 
Автор темы   Непрочитано 16.02.2012, 14:24
#10
Composter

Отопление и вентиляция
 
Регистрация: 31.10.2008
Москва
Сообщений: 445


действительно,у статических блоков и блоков с атрибутами нет 360 пары и 48 .но если программно сделать ConvertToAnonymousBlock или ConvertToStaticBlock ,то уних останутся эти пары.
Composter вне форума  
 
Непрочитано 16.02.2012, 15:59
#11
ciril

САПР
 
Регистрация: 29.09.2011
СПб
Сообщений: 283


Может так? На примерах из акадовского туториала динамические блоки отделяет. Хотя, учитывая количество операций, не уверен, что будет быстрей...
Код:
[Выделить все]
 (setq x00 (ssget "_X" '((0 . "INSERT")))
      x01 -1
      x02 (list))
(repeat (sslength x00)
  (or (eq 1
          (- (length
               (member (assoc 340
                              (setq x04 (entget
                                          (cdr
                                            (assoc 330
                                                   (entget (tblobjname "BLOCK" (cdr (assoc 2 (setq x03 (entget (ssname x00 (setq x01 (1+ x01))))))))))))))
                       x04))
             (length (member (assoc 102 x04) x04))))
      (setq x02 (append x02 (list (cdr (assoc -1 x03)))))))
(setq x00 nil)
ciril вне форума  
 
Непрочитано 16.02.2012, 17:52
#12
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 575


Composter, у меня есть такое предложение. Формировать набор не из всех вхождений блоков на чертеже с помощью (ssget '((0 . "INSERT"))), а сначала пройтись по определениям блоков и узнать имена динамических (обычно кол-во вхождений блоков намного больше чем определений), потом только сформировать набор с чертежа по вхождениям с именами дин. блоков и именами типа *U* и уже среди них проверить какие действительно являются динамическими. Такой вариант должен работать быстрее если среди всех вхождений много обычных, а не динамических блоков, так как мы их заранее отсеиваем, конечно если основная масса блоков динамические, то такой вариант будет наоборот работать дольше.
Код:
[Выделить все]
 
(defun sel_dyn_bloks( / ss i nbr ent lst)
  (vl-load-com)
  (setq ss ""
	i -1
	)
  (vlax-for blk_def (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (if (equal (vla-get-IsDynamicBlock  blk_def) :vlax-true)
      (setq ss (strcat ss (vla-get-Name blk_def) ","))
      )
    )
  (if (/= ss "")
    (progn
      (if (setq nbr (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat ss "`*U*")))))
	(repeat (sslength nbr)
	  (if (equal (vla-get-IsDynamicBlock  (vlax-ename->vla-object (setq ent (ssname nbr (setq i (1+ i)))))) :vlax-true)
	    (setq lst (cons ent lst))
	    )
	  )
	)
      )
    )
  lst
  ); end sel_dyn_bloks
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 16.02.2012, 21:40
#13
Composter

Отопление и вентиляция
 
Регистрация: 31.10.2008
Москва
Сообщений: 445


на счет количества блоков, на текущем моем чертеже их около 1500 из них динамических 600.на счет определенных имен,это вполне возможно(хоть их и около 30). и фильтр (cons 2 (strcat ss "`*U*")) не прокатывает если сделать _resetblock , то его текущее имя будет такое же как и vla-get-EffectiveName, и тогда он не попадет в этот список.
жаль по 360 паре не получается отсеивать ,и вот это тоже не прокатывает
Код:
[Выделить все]
 (ssget '((0 . "insert")(-4 . "*")(360 . 0)))

Последний раз редактировалось Composter, 16.02.2012 в 22:09.
Composter вне форума  
 
Непрочитано 16.02.2012, 22:07
#14
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 575


Цитата:
Сообщение от Composter Посмотреть сообщение
и фильтр (cons 2 (strcat ss "`*U*")) не прокатывает если сделать _resetblock , то его текущее имя будет такое же как и vla-get-EffectiveName, и тогда он не попадет в этот список.
Как это не попадает, попадает, его имя будет в строке ss, которое сформировано из имен определений блоков.
__________________
cadtools
TararykovDG вне форума  
 
Непрочитано 16.02.2012, 22:42
#15
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Composter Посмотреть сообщение
на текущем моем чертеже их около 1500 из них динамических 600
Может чего с компьютером не то? Такие порядки как не "обзамеряй" должен делать на счет раз (только что проверил на старом ноутбуке) - боюсь не туда смотрите.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Выделение блоков с динамическими свойствами



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Очистка рисунка от "пустых" блоков Makswell Готовые программы 15 26.10.2022 15:24
LISP. Нормализация блоков текущего файла. Кулик Алексей aka kpblc Готовые программы 82 06.07.2016 20:38
LISP / AutoCAD2008 / Как программно снять выделение у примитивов, не используя sssetfirst TararykovDG LISP 7 14.01.2011 10:48
Тормозит команда расчленения набора блоков batmax Программирование 4 31.08.2010 17:37
Быстрое выделение одинаковых блоков. Mikhail AutoCAD 24 17.02.2005 09:37