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

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

пытаюсь написать фильтр на LISP (помогите понять в чем ошибка)

Ответ
Поиск в этой теме
Непрочитано 12.01.2011, 16:11 #1
пытаюсь написать фильтр на LISP (помогите понять в чем ошибка)
Pontelimon
 
Регистрация: 16.11.2010
Сообщений: 89

Добрый день !

Я совсем недавно начал пытаться что-то сделать на Lisp так что прошу сильно не ругаться =)

Вот моя первый код, он должен выделять одно строчный текст, расположенный по оси Y < -75.

Код:
[Выделить все]
(defun vibor ( / )
  (setq nabor2 (ssadd))
  (setq nabor (ssget "_X" (list (cons 0 "TEXT") (cons 1 "*`.###"))))
  (if (null nabor)
      (progn
	(princ "\nНету подходящего текста. ")
	(princ)
      )
      (progn
	(setq i -1 kolichestvo_repeatov (sslength nabor))
	(repeat kolichestvo_repeatov
	  (setq i (1+ i))
	  (setq konkretniy_primitiv (entget (ssname nabor i)))
	  (setq koordinata_Y (caddr (assoc 10 konkretniy_primitiv)))
	  (if (koordinata_Y < -75)
	    (ssadd (konkretniy_primitiv) nabor2)
	    );end if
	    );end repeat
	  );end progn
    );end if
  (sssetfirst nil nabor2)
  (princ)
  );end defun
Но как Вы наверное уже догадались он не работает, почему ?

P.S. Очень прошу посмотреть что можно сделать именно в моем варианте решения данной задачи.
Просмотров: 10633
 
Непрочитано 12.01.2011, 16:26
#2
Лиспер


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


Расположенный по оси - это точка вставки у него ниже -75? А почему фильтруется по значению текста?
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 12.01.2011, 16:29
1 | #3
Дима_

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


Цитата:
Сообщение от Pontelimon Посмотреть сообщение
(if (koordinata_Y < -75)
это нормальная ошибка начинающих - вначале функция - (< koordinata_y 75)
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 12.01.2011, 16:29
#4
Pontelimon


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


Цитата:
Сообщение от Лиспер Посмотреть сообщение
Расположенный по оси - это точка вставки у него ниже -75? А почему фильтруется по значению текста?
Да, забыл просто написать, изначально выберется текст такого типа *`.###
Например: 125.889 или 1.089

2Дима_
Спасибо, буду внимательней =)


Подправил эту ошибку, выдаёт:
; ошибка: излишние cdrs в точесной паре на входе

Последний раз редактировалось Pontelimon, 12.01.2011 в 16:35.
Pontelimon вне форума  
 
Непрочитано 12.01.2011, 16:37
1 | #5
TararykovDG

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


Может так
Код:
[Выделить все]
(sssetfirst nil (ssget "_X" (list (cons 0 "TEXT") (cons 1 "*`.###") (cons -4 "*,<,*") (list 10 0.0 -75.0 0.0))))
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 12.01.2011, 16:45
#6
Pontelimon


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


Цитата:
Сообщение от TararykovDG Посмотреть сообщение
Может так
Код:
[Выделить все]
(sssetfirst nil (ssget "_X" (list (cons 0 "TEXT") (cons 1 "*`.###") (cons -4 "*,<,*") (list 10 0.0 -75.0 0.0))))
Да, так конечно решить эту задачу можно и решение намного практичнее, по сравнению с моим, но я хотел сделать это именно через 2 набора, чтобы понять ,как можно из 1 набора в другой передавать примитивы по какому-то определенному свойству.
Pontelimon вне форума  
 
Непрочитано 12.01.2011, 16:59
1 | #7
TararykovDG

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


Выделил красным
Код:
[Выделить все]
(defun vibor ( / )
  (setq nabor2 (ssadd))
  (setq nabor (ssget "_X" (list (cons 0 "TEXT") (cons 1 "*`.###"))))
  (if (null nabor)
      (progn
    (princ "\nНету подходящего текста. ")
    (princ)
      )
      (progn
    (setq i -1 kolichestvo_repeatov (sslength nabor))
    (repeat kolichestvo_repeatov
      (setq i (1+ i))
      (setq konkretniy_primitiv (entget (ssname nabor i)))
      (setq koordinata_Y (caddr (assoc 10 konkretniy_primitiv)))
      (if (koordinata_Y < -75)
        (ssadd (konkretniy_primitiv) nabor2) ; здесь скобки не нужны и вместо konkretniy_primitiv должно быть (ssname nabor i)
        );end if
        );end repeat
      );end progn
    );end if
  (sssetfirst nil nabor2)
  (princ)
  );end defun
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 12.01.2011, 17:12
#8
Pontelimon


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


2 TararykovDG
Ура ! получилось =)) Спасибо за пояснения !!!
А вот еще 1 вопрос по Вашему варианту в 1 строчку, я немного усложнил то что вы написали, посмотрите пожалуйста, что там не так:
Код:
[Выделить все]
(sssetfirst nil (ssget "_X" (list (cons 0 "TEXT") (cons 1 "*`.###")(-4 . "<OR") (cons -4 "*,>,*") (list 10 0.0 -75.0 0.0)(cons -4 "*,<,*") (list 10 0.0 -85.0 0.0)(-4 . "OR>"))))
Pontelimon вне форума  
 
Непрочитано 12.01.2011, 17:19
#9
Дима_

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


Вам наверное не or а and нужен.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 12.01.2011, 17:22
#10
Pontelimon


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


Мне нужно чтобы он выбрал текст находящийся либо выше -75 либо ниже -85, вроде тут OR нужен ?
А выдает он:
неверный тип аргумента: consp "<OR"

P.S. в моем коде vibor, у меня получилось это реализовать.
Pontelimon вне форума  
 
Непрочитано 12.01.2011, 17:40
1 | #11
VVA

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


Код:
[Выделить все]
(sssetfirst
  nil
  (ssget "_X"
         (list (cons 0 "TEXT")
               (cons 1 "*`.###")
               '(-4 . "<OR") ;_<=== апостроф в начале
               (cons -4 "*,>,*")
               (list 10 0.0 -75.0 0.0)
               (cons -4 "*,<,*")
               (list 10 0.0 -85.0 0.0)
               '(-4 . "OR>");_<=== апостроф в начале
         ) ;_ end of list
  ) ;_ end of ssget
) ;_ end of sssetfirst
При формировании списка важно различать когда элемент списка получается как результат выполнения функции (например (cons 0 "TEXT")), а когда передается статически (как есть), например (-4 . "OR>"). Во втором случае перед скобкой нужно ставить апостроф ('(-4 . "<OR")) или вызывать ф-цию quote
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 14.01.2011, 13:08
#12
Pontelimon


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


А почему вот этот фильтр ничего на находит ?

Код:
[Выделить все]
(ssget "_X"(list (cons 0 "TEXT")(cons -4 ">,>,*")(list 10 0.0 0.0 0.0)'(-4 . "<OR")(cons 1 "[4-9]#")(cons 1 "####")(cons 1 "###")'(-4 . ">OR")))
Причем если я подставляю туда что-то 1 из области OR (и соответственно уберу OR), то он работает как надо ... например вот так:

Код:
[Выделить все]
(ssget "_X"(list (cons 0 "TEXT")(cons -4 ">,>,*")(list 10 0.0 0.0 0.0)(cons 1 "###")))
Pontelimon вне форума  
 
Непрочитано 14.01.2011, 13:18
1 | #13
Лиспер


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


Без проверок:
Код:
[Выделить все]
(ssget "_X" '((0 . "TEXT") (-4 . ">,>,*") (10 0. 0. 0.) (1 . "[4-9]#,####,###")))
Сработает или нет - не знаю.
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 14.01.2011, 13:33
1 | #14
TararykovDG

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


Цитата:
Сообщение от Pontelimon Посмотреть сообщение
А почему вот этот фильтр ничего на находит ?

Код:
[Выделить все]
(ssget "_X"(list (cons 0 "TEXT")(cons -4 ">,>,*")(list 10 0.0 0.0 0.0)'(-4 . "<OR")(cons 1 "[4-9]#")(cons 1 "####")(cons 1 "###")'(-4 . ">OR")))
Причем если я подставляю туда что-то 1 из области OR (и соответственно уберу OR), то он работает как надо ... например вот так:

Код:
[Выделить все]
(ssget "_X"(list (cons 0 "TEXT")(cons -4 ">,>,*")(list 10 0.0 0.0 0.0)(cons 1 "###")))
В припципе Лиспер уже написал правильный вариант, а у Тебя Pontelimon,
Код:
[Выделить все]
это у Тебя
(ssget "_X"(list (cons 0 "TEXT")(cons -4 ">,>,*")(list 10 0.0 0.0 0.0)'(-4 . "<OR")(cons 1 "[4-9]#")(cons 1 "####")(cons 1 "###")'(-4 . ">OR")))
что должно быть
(ssget "_X"(list (cons 0 "TEXT")(cons -4 ">,>,*")(list 10 0.0 0.0 0.0)'(-4 . "<OR")(cons 1 "[4-9]#")(cons 1 "####")(cons 1 "###")'(-4 . "OR>")))
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 14.01.2011, 13:51
#15
Pontelimon


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


Всем спасибо, забыл что можно через запятую просто перечислить ... и не проверял написание т.к. LISP не выдавал ошибку.

Я тут написал написал продолжение своей первой програмки, причем оно даже работает(!). Смысл его в том что она получив набор из первой части начинает его округлять до сотых, я видел тут на форуме есть уже готовые решения с округлением, но я не всё там понимаю, поэтому решил попробовать написать самостоятельно.
Вот это произведение:
Код:
[Выделить все]
  (if (null nabor2)
      (progn
	(princ "\nНету подходящих цифр для округления. ")
	(princ)
      )
      (progn
	(setq i2 -1 kolichestvo_repeatov2 (sslength nabor2))
	(repeat kolichestvo_repeatov2
	(setq i2 (1+ i2))
	(setq konkretniy_primitiv2 (entget (ssname nabor2 i2)))
	(setq znachenie (cdr (assoc 1 konkretniy_primitiv2)))
	(setq znachenie_list (vl-string->list znachenie))
	(setq dlina_lista (length znachenie_list))
	(setq last_zifra (nth (- dlina_lista 1) znachenie_list ))
	(setq pre_last_zifra (nth(- dlina_lista 2)znachenie_list))
	(cond
	  ((>= last_zifra 54) 
	   	(setq novoe_znachenie '())
	   	(setq novoe_znachenie_ascii '())
		(setq i3 -1 kolichestvo_repeatov3 (length znachenie_list))
		(repeat (- kolichestvo_repeatov3 1)
		(setq i3 (1+ i3))
		(setq zifra_iz_spiska (nth i3 znachenie_list))
		(setq novoe_znachenie_ascii (append novoe_znachenie_ascii (list zifra_iz_spiska)))
		)
		(setq novoe_znachenie (vl-list->string novoe_znachenie_ascii))
	   	(setq novoe_znachenie (atof novoe_znachenie))
	   	(if (minusp novoe_znachenie)
		 (progn (setq novoe_znachenie(- novoe_znachenie 0.01)))
		 (progn (setq novoe_znachenie(+ novoe_znachenie 0.01)))
		)
	   	(setq novoe_znachenie (rtos novoe_znachenie 2 2))
	 	(setq konkretniy_primitiv2 (subst (cons 1 novoe_znachenie) (assoc 1 konkretniy_primitiv2)konkretniy_primitiv2))
	   	(entmod konkretniy_primitiv2)
	   )
	  ((<= last_zifra 52) 
	   	(setq novoe_znachenie '())
	   	(setq novoe_znachenie_ascii '())
		(setq i3 -1 kolichestvo_repeatov3 (length znachenie_list))
		(repeat (- kolichestvo_repeatov3 1)
		(setq i3 (1+ i3))
		(setq zifra_iz_spiska (nth i3 znachenie_list))
		(setq novoe_znachenie_ascii (append novoe_znachenie_ascii (list zifra_iz_spiska)))
		)
		(setq novoe_znachenie (vl-list->string novoe_znachenie_ascii))
	 	(setq konkretniy_primitiv2 (subst (cons 1 novoe_znachenie) (assoc 1 konkretniy_primitiv2)konkretniy_primitiv2))
	   	(entmod konkretniy_primitiv2)
	   )
	  ((and (= last_zifra 53) (or(= pre_last_zifra 48) (= pre_last_zifra 50) (= pre_last_zifra 52)(= pre_last_zifra 54)(= pre_last_zifra 56)))
	   	(setq novoe_znachenie '())
	   	(setq novoe_znachenie_ascii '())
		(setq i3 -1 kolichestvo_repeatov3 (length znachenie_list))
		(repeat (- kolichestvo_repeatov3 1)
		(setq i3 (1+ i3))
		(setq zifra_iz_spiska (nth i3 znachenie_list))
		(setq novoe_znachenie_ascii (append novoe_znachenie_ascii (list zifra_iz_spiska)))
		)
		(setq novoe_znachenie (vl-list->string novoe_znachenie_ascii))
	 	(setq konkretniy_primitiv2 (subst (cons 1 novoe_znachenie) (assoc 1 konkretniy_primitiv2)konkretniy_primitiv2))
	   	(entmod konkretniy_primitiv2)	   
	   )
	  ((and (= last_zifra 53) (or(= pre_last_zifra 49) (= pre_last_zifra 51) (= pre_last_zifra 53)(= pre_last_zifra 55)(= pre_last_zifra 57)))
	   	(setq novoe_znachenie '())
	   	(setq novoe_znachenie_ascii '())
		(setq i3 -1 kolichestvo_repeatov3 (length znachenie_list))
		(repeat (- kolichestvo_repeatov3 1)
		(setq i3 (1+ i3))
		(setq zifra_iz_spiska (nth i3 znachenie_list))
		(setq novoe_znachenie_ascii (append novoe_znachenie_ascii (list zifra_iz_spiska)))
		)
		(setq novoe_znachenie (vl-list->string novoe_znachenie_ascii))
	   	(setq novoe_znachenie (atof novoe_znachenie))
	   	(if (minusp novoe_znachenie)
		 (progn (setq novoe_znachenie(- novoe_znachenie 0.01)))
		 (progn (setq novoe_znachenie(+ novoe_znachenie 0.01)))
		)
	   	(setq novoe_znachenie (rtos novoe_znachenie 2 2))
	 	(setq konkretniy_primitiv2 (subst (cons 1 novoe_znachenie) (assoc 1 konkretniy_primitiv2)konkretniy_primitiv2))
	   	(entmod konkretniy_primitiv2)
	   )				
	 );end cond
	 );end repeat
  (setvar 'dimzin 8)
  (princ "\nКоличество округленных цифр ")
  (princ(sslength nabor2))
  (princ)
  )
  );end if
Буду признателен за замечания и советы.
Pontelimon вне форума  
 
Непрочитано 14.01.2011, 13:55
#16
VVA

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


Цитата:
Сообщение от Pontelimon Посмотреть сообщение
Буду признателен за замечания и советы.
После замечаний и советов может получиться
Цитата:
Сообщение от Pontelimon Посмотреть сообщение
я видел тут на форуме есть уже готовые решения с округлением, но я не всё там понимаю
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 14.01.2011, 16:35
#17
Pontelimon


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


Я тут еще прикинул небольшой код, который должен опускать по оси Y некоторые цифры, но я никак не пойму, почему он опускает только 3 цифры ?!
Код:
Код:
[Выделить все]
(defun c:oform ( /)
 (setq nabor5(ssget "_X"(list (cons 0 "TEXT")(cons -4 "*,>,*")(list 10 0.0 0.0 0.0)'(-4 . "<OR")(cons 1 "[4-9]#")(cons 1 "####")(cons 1 "###")'(-4 . "OR>"))))
 (if (null nabor5)
      (progn
	(princ "\nНет цифр. ")
	(princ)
      )
        (progn
        (setq i5 -1 kolichestvo_repeatov5 (sslength nabor5))
	(repeat kolichestvo_repeatov5
	(setq novie_koord '())
	(setq i5 (1+ i5))
	(setq konkretniy_primitiv5 (entget (ssname nabor5 i5)))
	(setq koordX (cadr (assoc 10 konkretniy_primitiv5)))
	(setq koordY (caddr (assoc 10 konkretniy_primitiv5)))
	(setq koordZ 0.0)
	(setq koordY (- koordY 1))
	(setq novie_koord (append novie_koord (list koordX)))
	(setq novie_koord (append novie_koord (list koordY)))
	(setq novie_koord (append novie_koord (list koordZ)))      
	(setq konkretniy_primitiv5 (subst (cons 10 novie_koord) (assoc 10 konkretniy_primitiv5)konkretniy_primitiv5))
	(entmod konkretniy_primitiv5)
	)
        (princ)
	)
   	)
        )
Ну и файл с цифрами, на котором я ставил эксперимент прилагаю.
Вложения
Тип файла: dwg
DWG 2010
Чертеж.dwg (57.0 Кб, 908 просмотров)

Последний раз редактировалось Pontelimon, 14.01.2011 в 22:26.
Pontelimon вне форума  
 
Непрочитано 15.01.2011, 01:49
1 | #18
Кулик Алексей aka kpblc
Moderator

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


Подозреваю, что дело в выравнивании текста...
http://autolisp.ru/2010/04/06/text-and-attrib-entities/
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.01.2011, 13:32
#19
Pontelimon


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


Никогда бы не подумал что выравнивание может так влиять на это, вот новый рабочий вариант:
Код:
[Выделить все]
 (setq nabor5(ssget "_X"(list (cons 0 "TEXT")(cons -4 "*,>,*")(list 10 0.0 0.0 0.0)'(-4 . "<OR")(cons 1 "[4-9]#")(cons 1 "####")(cons 1 "###")'(-4 . "OR>"))))
 (if (null nabor5)
      (progn
	(princ "\nâàõ!. ")
	(princ)
      )
        (progn
        (setq i5 -1 kolichestvo_repeatov5 (sslength nabor5))
	(repeat kolichestvo_repeatov5
	(setq novie_koord '())
	(setq i5 (1+ i5))
	(setq konkretniy_primitiv5 (entget (ssname nabor5 i5)))
	(setq koordX (cadr (assoc 10 konkretniy_primitiv5)))
	(setq koordY (caddr (assoc 10 konkretniy_primitiv5)))
	(setq koordZ 0.0)
	(setq koordY (- koordY 1))
	(setq novie_koord (append novie_koord (list koordX)))
	(setq novie_koord (append novie_koord (list koordY)))
	(setq novie_koord (append novie_koord (list koordZ)))      
	(setq konkretniy_primitiv5 (subst (cons 72 0) (assoc 72 konkretniy_primitiv5)konkretniy_primitiv5))
	(entmod konkretniy_primitiv5)
	(setq konkretniy_primitiv5 (subst (cons 10 novie_koord) (assoc 10 konkretniy_primitiv5)konkretniy_primitiv5))
	(entmod konkretniy_primitiv5)
	)
	(princ)
	)
   	)
  )
Pontelimon вне форума  
 
Автор темы   Непрочитано 17.01.2011, 16:25
#20
Pontelimon


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


Тут возникло еще пару вопросов:

Как можно на лиспе вставить блок который находиться у меня на закладке Палитра в точку с координатами 0,0 ? Так же при вставке с палитры он у меня автоматически расчленяться.

Сам блок находиться в файле: D:\%CADRootDir%\Палитры\Specificacia.dwg
Называется: Профиль В

Как можно получить координаты точки вставки блока ? (хочу их использовать в фильтре)
Pontelimon вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > пытаюсь написать фильтр на LISP (помогите понять в чем ошибка)

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Несоответствие результатов в Лире s.vas Лира / Лира-САПР 19 11.11.2009 07:31
Пожалуста помогите правельно написать формулу для Schedule- спецификации tighineanur Вертикальные решения на базе AutoCAD 6 24.02.2009 11:24
Помощь по Лире Серега М Лира / Лира-САПР 52 28.05.2007 02:47
Не могу понять в чем ошибка... DY Программирование 5 21.02.2007 17:35