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

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

Lisp. Вывод нужных элементов блока с учётом вложенных блоков.

Ответ
Поиск в этой теме
Непрочитано 06.08.2011, 18:45 #1
Lisp. Вывод нужных элементов блока с учётом вложенных блоков.
молодой человек
 
Регистрация: 14.11.2007
Сообщений: 159

Здравствуйте!
Интуитивно догадываюсь, что лучше сделать с помощью рекурсии.
Но как-то не заладилось с рекурсией(

Код:
[Выделить все]
 
;;;(setq list_ent nil)
;;;(kos-search-all-elements-in-block (car(entsel))"*AECS_MEMBER,AEC_MASS_ELEM")
(defun kos-search-all-elements-in-block (block name / en  )
  (setq en (entnext (tblobjname "block" (cdr (assoc 2 (entget block))))));
  (while en
    (cond
      ((wcmatch (cdr (assoc 0 (entget en))) name)
        ;; 
       (setq list_ent (append list_ent (list en)))
      )
      ((wcmatch (cdr (assoc 0 (entget en))) "INSERT")
       (kos-search-all-elements-in-block en "*AECS_MEMBER,AEC_MASS_ELEM" )
      )
    )
    (setq en (entnext en))
  ) 
  list_ent
);defun kos-search-all-elements-in-block
Все найденные элементы накапливаю в переменную list_ent .
Поэтому приходится обнулять её перед выполнением функции.

Как правильно решить данную задачу, чтобы не обнулять каждый раз переменную list_ent ?
Просмотров: 2651
 
Непрочитано 06.08.2011, 20:39
1 | #2
Дима_

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


Цитата:
Сообщение от молодой человек Посмотреть сообщение
(setq list_ent (append list_ent (list en)))
Подумайте что происходит в этой строчке (а Вы ее вызываете в цикле) избавивишись от нее у Вас получится "правильное" (без "лишних" действий) решение - задачу прекрасно можно решить как итеративно, так и рекурсивно.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 07.08.2011, 00:24
#3
gomer

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


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Подумайте что происходит
если не знаете куда думать, почитайте про глобальные и локальные переменные и способы их объявления
еще подумайте по поводу переменной en ... не много ли ей чести...
и напоследок подумайте о переменной name... что ж вы все таки ищете в блоках... какая глубина поиска (вложенность блоков)
gomer вне форума  
 
Автор темы   Непрочитано 07.08.2011, 18:40
1 | #4
молодой человек


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


Цитата:
Подумайте что происходит в этой строчке
Спасибо Вам за замечания, но не заладилось у меня и всё тут.
В результате нужно иметь один список, без подсписков из найденных элементов.
В итоге вот такой код, результатом его работы является список нужных элементов,
где первым элементом стоит анализируемый элемент. Работает как надо, но не покидает
ощущение, что сделано через попу) Может есть какие-то идеи как оптимизировать данный код?
Код:
[Выделить все]
 ;;;-------------Функция выводит в список вхождений блока по названию нужного элемента через таблицу блоков с учётом вложенных блоков-----------------------
;;;             Первым элементом списка является рассматриваемый блок, а далее искомые элементы
;;;(kos-search-all-elements-in-block (car(entsel))"*LINE")
;;;(kos-search-all-elements-in-block (car(entsel))"INSERT")
;;;(kos-search-all-elements-in-block (car(entsel)) "*AECS_MEMBER,AEC_MASS_ELEM")

(defun kos-search-all-elements-in-block (block name / list_ent   )
   
  (defun kos-search-sub-elements-in-block (block name / en   )
    (setq  en  (tblobjname "block" (cdr (assoc 2 (entget block)))));en- представление блока в словаре
    (while (setq en (entnext en))
      (cond
        ((wcmatch (cdr (assoc 0 (entget en))) name)
          ;; Добираемся до искомого элемента и накапливаем в переменную 
         (setq list_ent (append (list en) list_ent ))
	 
        )
      )
      (if (wcmatch (cdr (assoc 0 (entget en))) "INSERT")
	   (kos-search-sub-elements-in-block en name)
      )
     )
  );defun kos-search-all-elements-in-block
  
  (setq list_ent (list block))
  (kos-search-sub-elements-in-block block name)
  (reverse list_ent)
)
молодой человек вне форума  
 
Непрочитано 07.08.2011, 22:43
2 | #5
Кулик Алексей aka kpblc
Moderator

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


Если порядок примитивов не сильно критичен, то как вариант:
Код:
[Выделить все]
(vl-load-com)

(defun _dwgru-ent-search-in-block (blk-ref lst / res)
				  ;|
*    Выполняет поиск элементов внутри блока
*    Параметры вызова:
  blk-ref  указатель на вхождение блока (ename или vla)
  lst      список дополнительных параметров вида
  '(("type" . <Маска имени искомого примитива>)
    ("in" . <Выполнять поиск внутри вложенных блоков>)
    )
*    Примеры вызова:
    ; ищет все примитивы без поиска внутри вложенных блоков:
(_dwgru-ent-search-in-block (car (entsel)) nil)
    ; ищет все примитиву с "заходом" внутрь вложенных блоков:
(_dwgru-ent-search-in-block (car (entsel)) '(("in" . t)))
    ; ищет все примитивы с маской *line (отрезки, полилинии, сплайны)
    ; с заходом внутрь вложенных блоков:
(_dwgru-ent-search-in-block (car (entsel)) '(("in" . t) ("type" . "*line")))
    ; ищет все примитивы с маской *line (отрезки, полилинии, сплайны)
    ; без захода внутрь вложенных блоков:
(_dwgru-ent-search-in-block (car (entsel)) '(("type" . "*line")))
|;
  (cond
    ((= (type blk-ref) 'ename)
     (setq res (_dwgru-ent-search-in-block (vlax-ename->vla-object blk-ref) lst))
     )
    ((and (= (type blk-ref) 'vla-object)
	  (= (vla-get-objectname blk-ref) "AcDbBlockReference")
	  ) ;_ end of and
     (vlax-for subent (vla-item (vla-get-blocks (vla-get-document blk-ref)) (vla-get-name blk-ref))
       (cond
	 ((and (cdr (assoc "in" lst)) (= (vla-get-objectname subent) "AcDbBlockReference"))
	  (setq res (append res (_dwgru-ent-search-in-block subent lst)))
	  )
	 ((wcmatch (strcase (vla-get-objectname subent))
		   (strcase (cond
			      ((cdr (assoc "type" lst)))
			      (t "*")
			      ) ;_ end of cond
			    ) ;_ end of strcase
		   ) ;_ end of WCMATCH
	  (setq res (cons subent res))
	  )
	 ) ;_ end of cond
       ) ;_ end of vlax-for
     (setq res (reverse res))
     )
    ) ;_ end of cond
  res
  ) ;_ end of defun
P.S. Особо код не проверял. Внешние ссылки не фильтруются.
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.01.2013, 21:41
#6
sdv79

Инженер ЭОМ
 
Регистрация: 05.03.2009
Москва
Сообщений: 215
Отправить сообщение для sdv79 с помощью Skype™


Кулик Алексей aka kpblc спасибо.
Динамический блок (светильник) с единственным прямоугольником (полилиния, задана высота 3D) читаю
Код:
[Выделить все]
 (setq qwe (_dwgru-ent-search-in-block (car (entsel)) '(("type" . "*line"))) )
(setq qwe1 (car qwe))
ПКМ(пр. кнопка мыши) изучить qwe1 вижу ее как Thickness.
Подскажите как ее прочитать/модифицировать, и как изменить габариты самого прямоугольника (сделать стороны 1х3)?
Вложения
Тип файла: dwg
DWG 2013
Чертеж2.dwg (40.8 Кб, 893 просмотров)
sdv79 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Lisp. Вывод нужных элементов блока с учётом вложенных блоков.

Инженерные консультации
Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание дополнительных параметров Visibility Set в динамических блоках. Supermax Программирование 708 12.04.2021 14:54
Документация Проектировщику на Torrents DEM Разное 259 04.03.2020 08:17
LISP. Очистка рисунка от "пустых" блоков Makswell Готовые программы 12 10.09.2015 14:31
Порекомендуйте литературу для повышения квалификации(грунты, геотехника) acid Поиск литературы, чертежей, моделей и прочих материалов 6 13.05.2015 22:14
Lisp: Список элементов в слоях ALFMario LISP 4 29.04.2008 17:26