Тема: Как пронумеровать атрибуты?
Как пронумеровать атрибуты ...
Есть 450 атрибутов ... и им надо присвоить "последовательные значения" (1, 2, 3 ...)
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → Программирование → LISP → Как пронумеровать атрибуты?
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Как пронумеровать атрибуты ...
Есть 450 атрибутов ... и им надо присвоить "последовательные значения" (1, 2, 3 ...)
Есть же там всякие тэги....
А если надо просто организовать их последовательность, то мона просто использовать BATTMAN
У атрибута тег один.
Суть в том, что есть полилиния в вершины которой вставлены атрибуты. Моя задача состоит в том чтобы пронумеровать их и через "_eattext" вытащить координаты их точек вставки.
Р.S. Я не програмер..
С уважением!
Попробую угадать подробности задачи....
полилиния в вершины которой вставлены атрибуты
вытащить координаты их точек вставки
Другими словами... 1/2 задачи - вытащить координаты вершин полилинии в текстовый файл,
а вторая половина задачи - проставить в атрибуте (какого то блока, вставленного в каждую вершину полилинии) порядковый номер вершины...
Ручками делать лень (жара патамушта), нужна программа. Так?
Что значит " вставлены атрибуты"
Может быть ето блоки с атрибутами?
> VK
Будьте добры, помогите, меня тоже интересует решение этой задачи, особенно первой ее части.
В моем случае в вершины полилинии вставлено по одному блоку, содержащему по одному атрибуту. Нужно, чтобы функция могла:
- не обращать внимания на имеющиеся значения атрибутов (для случая редактирования после удаления/добавления вершин и блоков);
- если вершина полилинии не содержит блока, то переходить к следующей;
- если две и более вершин имеют одинаковые координаты (у меня 2D), то обрабатывать только один раз - бывает случаи редактирования полилинии, когда ненужный сегмент полилинии скрывается совмещением соседних вершин;
- номер в общем случае может иметь постоянный префикс, запрашиваемый в начале работы функции.
Применеие данной функции очень поможет при проектировании шлейфов пожарной сигнализации.
Короче говоря...
1. Надо пронумеровать у нескольких полилиний все вершины.
2. Создать таблицу с координатами каждой вершини. (каждому номеру вершины соответствуют свои координаты)
> Любознательный
Для первой части (вывод координат в текстовый файл) есть уже не одна прожка... Вот для LWPOLYLINE
(defun c:lwcoord2txt (/ ss l:coord fname ff) (if (and (princ "\nПолилиния > ") (setq ss (ssget "_:S" '((0 . "LWPOLYLINE")))) (setq l:coord (apply 'append (mapcar '(lambda (el) (if (= 10 (car el)) (list (trans (cdr el) 0 1)) ;_перевод в текущую ПСК ) ;_ if ) ;_ lambda (entget (ssname ss 0)) ) ;_ mapcar ) ;_ apply ) ;_ setq ) ;_ and (progn ;; открытие файла для записи (setq fname (strcat (getvar "dwgprefix") (vl-string-right-trim "dwg" (getvar "dwgname")) "ptc")) (if (findfile fname) (progn (alert (strcat "\nФайл " fname " существует. Данные будут добавлены в конец файла.")) (setq ff (open fname "a")) ) ;_ progn (progn (alert (strcat "\nДанные будут записаны в файл " fname)) (setq ff (open fname "w")) ) ;_ progn ) ;_ if ;; запись в файл (write-line "->->->->" ff) (mapcar '(lambda (x) (write-line (vl-string-trim "()" (vl-princ-to-string x)) ff)) l:coord) (write-line "<-<-<-<-" ff) (close ff) ;_ закрытие файла ) ;_ progn ) ;_ if (princ) ) ;_ defun (vl-load-com) ;; автозапуск (c:lwcoord2txt)
В принципе, они не сложные и более-менее похожи...
В моем случае в вершины полилинии вставлено по одному блоку, содержащему по одному атрибуту.
....
- если вершина полилинии не содержит блока, то переходить к следующей;
Есть еще варианты: блок содержится (другой, не с описанием вершины) но без атрибутов или не с одним, а бОльшим их количеством; в точку вершины вставлен не один а два, три пять блоков.... И че делать? Наверно все ж искать по заданному имени. Или не глядя на существующие, просто воткнуть новый блок. Это надо обдумать....
> Papila
Пронумеровать - не проблема. О засадах по блокам с атрибутами - чуть выше. И есть еще одна засада - последовательность номеров. Варианты - от начала до конца, от конца до начала, от начала до конца но началом считать конец полилинии с меньшим (или бОльшим) значением координаты X (или Y)... Засада - в случае с замкнутой полилинией.
Создать таблицу
Это таблица Excel или таблица ACAD2005 или набор текстов и отрезков, представляющих изображение таблицы?
> VK
Большое спасибо, но под первой частью задачи я имел ввиду нумерацию...
У меня будет использоваться 3 типа блока с 1 атрибутом. Да, проверять по именам. Другие игнорировать. Последовательность - строго от начала к концу, это важно. Начало - это стартовая точка отрисовки полилинии. Перебор - как в команде pedit edit vertex.
Надеюсь на помощь!
Вот как мы друг друга поняли :)))
Ну ежли так то спробуй вот этот код:
(defun c:lwvertnum (/ ss l:coord num) (if (and (princ "\nПолилиния > ") (setq ss (ssget "_:S" '((0 . "LWPOLYLINE")))) (setq l:coord (apply 'append (mapcar '(lambda (el) (if (= 10 (car el)) (list (cdr el)) ) ;_ if ) ;_ lambda (entget (ssname ss 0)) ) ;_ mapcar ) ;_ apply ) ;_ setq ) ;_ and (progn (setq num 1) (while l:coord (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 10 (car l:coord)) '(2 . "NUMBLOCK1,NUMBLOCK2,NUMBLOCK3")))) (vla-put-textstring (vlax-ename->vla-object (entnext (ssname ss 0))) (rtos num 2 0)) ) (setq l:coord (cdr l:coord)) (setq num (1+ num)) ) ) ;_ progn ) ;_ if (princ) ) ;_ defun (vl-load-com) (c:lwvertnum);_ автозапуск
Конечно все предельно упрощено, не проверяю наличие атрибута. Предполагается что он есть, ведь имена блоков для правки четко определены. В '(2 . "NUMBLOCK1,NUMBLOCK2,NUMBLOCK3") перечисли свои имена блоков.
Мдя... наверно надо чуток поправить код, чтоб блоки выбирались только в Модели... Вот так:
... (if (setq ss (ssget "_X" (list '(0 . "INSERT") [b]'(410 . "Model") [/b] (cons 10 (car l:coord)) ...
Да мало ли какие еще проблемки могут возникнуть....
> VK
Все работает...но только с одной ролилинией а надо с несколькими...
С уважением!
> VK
И еще странность ... у меня 405 блоков а прога нумерует аж до 488 (нашел два 21 номера)... (в полилинии много сдвоенных вершин)
> Papila
Вобще то у Вас в > Papila (2004-08-21 12:03:45) было сказано
1. Надо пронумеровать у нескольких полилиний все вершины.
Скорей всего, в полилини есть "двойные" вершины. Может быть, двойные (тройные и т.д.) игнорировать? А вот откуда два 21 номера взялись - не соображу.
Для нескольких полилиний - нумерация сквозная (в порядке последовательности выбора) или для каждой с 1?
Попробуйте такой код. Почти не тестировал.
(defun c:lwsvertnum (/ remove-eq ss ssP l:coord num) (defun remove-eq (lst / res) (if (car lst) (if (equal (car lst) (car (setq res (remove-eq (cdr lst))))) res (cons (car lst) res) ) ;_ if ) ;_ if ) ;_ defun (if (and (princ "\nПолилинии > ") (setq ssp (ssget '((0 . "LWPOLYLINE"))))) (while (> (sslength ssp) 0) (setq l:coord (remove-eq (apply 'append (mapcar '(lambda (el) (if (= 10 (car el)) (list (cdr el)) ) ;_ if ) ;_ lambda (entget (ssname ssp 0)) ) ;_ mapcar ) ;_ apply ) ;_ remove-eq ) ;_ setq (setq ssp (ssdel (ssname ssp 0) ssp)) (setq num 1) (while l:coord (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(410 . "Model") (cons 10 (car l:coord)) '(2 . "NUMBLOCK1,NUMBLOCK2,NUMBLOCK3") ;_ имена блоков с атрибутами для правки ) ;_ list ) ;_ ssget ) (vla-put-textstring (vlax-ename->vla-object (entnext (ssname ss 0))) (rtos num 2 0)) ) ;_ if (setq l:coord (cdr l:coord)) (setq num (1+ num)) ) ;_ while ) ;_ while ) ;_ if (princ) ) ;_ defun (vl-load-com) (c:lwsvertnum) ;_ автозапуск
> VK
что касательно функции удаляющей дубликаты вершин...
нарисовал прямоугольник в орто с координатами, причём вводил 50, 100, 50 и 100, заметь последнюю:
((0.0 0.0) (0.0 50.0) (100.0 50.0) (100.0 0.0) (-7.87564e-015 0.0))
твоя функция не удалит её, написал такую:
(defun REMDOUBLE2 (PROCLIST PRECISION / FIRST OTHER) (if (setq FIRST (car PROCLIST)) (cond ((setq OTHER (cdr PROCLIST)) (cond ((member 't (mapcar '(lambda (X) (equal FIRST X PRECISION)) OTHER)) (REMDOUBLE2 OTHER PRECISION)) (t (cons FIRST (REMDOUBLE2 OTHER PRECISION))) )) (t (list FIRST)) ) ;_ end of cond ) ;_ end of if ) ;_ end of defun
вызов:
(REMDOUBLE2 (YOUR_LINEVERTEXES (car (entsel))) 0.001)
> DMS
Да, я тоже подумал об этом эээ... даже не ляпсусе (с точки зрения списков вроде бы все корректно), а скорее, особенности АКАДа. Потому, о другом варианте подумалось сегодня с утра. Изменения минимальны: вместо equal использовать distance и соответственно проверять, не больше ли дистанция некоторой величины. Вроде вот этого (не проверял)
(if (< (distance (car lst) (car (setq res (remove-eq (cdr lst))))) 0.0001)
> VK
мне кажется, что здесь просто проявляются особенности твоего алгоритма рекурсии, предназначенного именно для схожих точек следующих друг за другом, т.к. небольшая переделка доказывает это:
(setq QQQ (YOUR_LINEVERTEXES (car (entsel))))
даёт
((0.0 0.0) (0.0 50.0) (100.0 50.0) (100.0 0.0) (-7.87564e-015 0.0))
(remove-eq (append (list (car QQQ)) (list (last QQQ)) (reverse (cdr (reverse (cdr QQQ))))))
даёт
((-7.87564e-015 0.0) (0.0 50.0) (100.0 50.0) (100.0 0.0))
но только remove-eq уже подправил так:
(defun remove-eq (lst / res) (if (car lst) (if (equal (car lst) (car (setq res (remove-eq (cdr lst)))) 0.0001) res (cons (car lst) res) ) ;_ if ) ;_ if ) ;_ defun
P.S. сравнил по времени твой и свой варианты на 10000 циклов, мой на порядок медленнее :(, правда чуть универсальнее :).
> VK
Для нескольких полилиний - нумерация сквозная (в порядке последовательности выбора)
> DMS
Да, именно для схожих точек следующих друг за другом и вот почему... Потому как в принципе полилиния может и пересекать себя в том числе и в вершине... НО! какой же элемент списка из совпадающих в этом случае удалять - первый или второй? Хотя, (имхо) это частный случай и требует отдельного рассмотрения. А удалять именно парные вершины мне кажется совершенно логичным - скорей всего это нежелание "отдельных тварисчей" удалить лишнюю вершину PEDIT'ом.
А вот это
(equal (car lst) (car (setq res (remove-eq (cdr lst)))) [b]0.0001[/b])
Честно говоря, никогда не задумывался что можно так сделать!!! Это "допуск" по каждому элементу сравниваемых списков или что то другое?
> Papila
Для сквозной нумерации убери (или закомментируй) сброс счетчика вершин
;;; (setq num 1)
/эээхххх... и кому только говорили "пишите комментарии в коде!" - это я себе/
> Papila
Нет, вру!!!
Не убери, а перенеси строку
(setq num 1)
выше. Сделай ее ну например второй (следующей после defun)
> VK
думаю Papila сам разберётся какую функцию лучше ему использовать для своей специфики...
про вот это
честно говоря, сначала сам просто интуитивно попробовал - получилось, а когда ты обратил внимание, то посмотрел и...
прямо из help'а для equal:
...When comparing two real numbers (or two lists of real numbers, as in points), the two identical numbers can differ slightly if different methods are used to calculate them. You can specify a fuzz amount to compensate for the difference that may result from the different methods of calculation...
> VK
Большое спасибо, работает.
Если не затруднит, измените немного код для меня:
- номер должен иметь постоянный префикс, запрашиваемый в начале работы функции.
- в атрибут писать не номер вершины, а номер блока, или (что тоже самое номер вершины, "содержащей" блок - у меня не все вершины полилинии "содержат" блоки).
Префикс/суффикс:
(defun c:lwsvertnum (/ remove-eq ss ssp l:coord num [b]pref suff[/b]) [b](setq pref (getstring "\nПрефикс: ")) (setq suff (getstring "\nСуффикс: "))[/b]
Это в начале... и далее еще в одном месте немного подправить
(vla-put-textstring (vlax-ename->vla-object (entnext (ssname ss 0))) [b](strcat pref (rtos num 2 0) suff)[/b])
Не проверял, но вроде должно работать. Надеюсь, разберетесь и оставите кому что нужно
в атрибут писать не номер вершины, а номер блока
Это вроде "посчитать блоки в вершинах а не сами вершины" ?
Скорей всего, изменить примерно так (тоже не проверял):
) ;_ ssget ) (progn (vla-put-textstring (vlax-ename->vla-object (entnext (ssname ss 0))) (rtos num 2 0)) (setq num (1+ num)) ;_ приращение номера ) ;_ progn ) ;_ if (setq l:coord (cdr l:coord)) ) ;_ while ) ;_ while
Конечно, если в вершине несколько блоков, с допустимыми именами, то все равно они все будут посчитаны за один.
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Форумы CADUser → Программирование → LISP → Как пронумеровать атрибуты?
Форум работает на PunBB, при поддержке Informer Technologies, Inc