Re: Программа+макрос на кнопку "Удаление повторяющихся элементов" для AutoCAD 2006
> Forma
Есть другие предложения? Мне просто самому уже интересно, чем дело закончится.
И все в одном слое, одним цветом и т.п. ?
А как вручную это делалось?
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → LISP → Программа+макрос на кнопку "Удаление повторяющихся элементов" для AutoCAD 2006
> Forma
Есть другие предложения? Мне просто самому уже интересно, чем дело закончится.
И все в одном слое, одним цветом и т.п. ?
А как вручную это делалось?
> Runa
Я веду речь не об имени примитива, а об метке из 5-го кода dxf. С именами вряд ли получится они пересчитываются при каждой загрузке рисунка.
> Forma
По идее должно работать если по предложеной схеме (см. выше) вы визуально сможете контролировать выделение и не поленитесь раз 1000 нажать на Enter (может и меньше если выделять примитивов по 10).
Самому писать недосуг. Может кто проверит идею?
> AY
Интересно как выглядят метки после массивного размножения сразу нескольких примитивов?
Допустим я выделил сразу 10 линий и размножил массивом...
> kpblc
"...А как вручную это делалось?.."
Размножил метки, красные кружочки, по ходу следования. А потом удалял вручную. Пока не о...
Потом стал писать на форум.
> AY
"...поленитесь раз 1000 нажать на Enter..." Спасибо. Именно этого и ждал.
Можно просто прошарить всю базу примитивов чертежа, по порядку создания объекта(ов). Получится офигительный вычеслительная работа со списком объектов на повторения в отдельности и в группах. Всё это можно будет еще фильтровать несколькими способами, итерациями.
Мне даже стало интересно. Надо будет подумать на досуге.
А разве в LISP невозможно найти конкретные обьекты с конкретными данными и удалить все? В TurboBasic я это все делал легко. Машины были слабые. Это да. Короче, я эту задачу решил в старом текстовом редакторе "Foton" для DOS. Догадайтесь с одного раза. Как это у меня получилось.
Опасная вещь "Потеря контроля на стадии проектирования". Линии рисуются как попало, тексты расползаются и по горизонтали и по вертикали, объекты неуправляемо размножаются...
Прямо потеря контроля на стадии существования, IMHO.
Вот вылупилась опасная, мерзкая программа:
;************** er_ar.lsp ********************************************************* ; Программа, обратная массиву. Стирает объекты с ; заданным шагом по осям X и Y. Шаги должны быть ; точно определены и заданы такими же, какие ; использовались в массиве. Сначала удаляются ; объекты по осям X и Y, потом диагональные объекты. ; Не рекомендуется пропускать удаление ортогональных ; объектов, иначе можно запутаться. Здесь вообще ; можно запутаться, поэтому лучше сначала проверить ; работу программы в пустом рисунке с разными массивами. ; ; Разработал [b]Profan[/b]. ; (defun C:ER_AR ( / sx sy flag p1x p1y px py p1xy pxy) (setvar "CMDECHO" 0) (setq sx (getint "\n Шаг по оси X: ")) (setq sy (getint "\n Шаг по оси Y: ")) (setq flag T) (while flag (setq p1x (getpoint "\n Укажите точку на объекте-шаблоне (Enter-закончить): ")) (if p1x (progn (setq p1y p1x p1xy p1x) (repeat 1000 (setq px (list (+ (car p1x) sx) (cadr p1x))) (command "_ERASE" px "") (setq p1x px) ); repeat (repeat 1000 (setq py (list (car p1y) (+ (cadr p1y) sy))) (command "_ERASE" py "") (setq p1y py) ); repeat ); progn (setq flag nil) ); if ); while (setq p1xy (getpoint "\n Укажите точку на диагональном объекте-шаблоне (Enter-отказ): ")) (if p1xy (progn (repeat 1000 (setq pxy (list (+ (car p1xy) sx) (+ (cadr p1xy) sy))) (command "_ERASE" pxy "") (setq p1xy pxy) ); repeat ); progn ); if (princ) )
Возможный макрос для кнопки или пункта меню:
^C^C^P(if (not C:ER_AR) (load "er_ar") ER_AR
Я проверял ее только в пустом рисунке - нарисовал прямоугольник и размножил его массивом, а потом стер этой программой. Остался только исходный прямоугольник. Надо сохранить рабочий рисунок и подумать еще, использовать ли эту программу. За все неприятности пусть отвечает Profan.
> Владимир Громов
Сейчас буду проверять. А как Вам мое решение? Тряхнул стариной:)
За все неприятности пусть отвечает Profan.
:^D
> Forma
А где это решение? Мое решение - грубое, ломом в лоб. Что там сотрется на самом деле, одному Богу известно.
А вот:
"... разве в LISP невозможно найти конкретные обьекты с конкретными данными и удалить все? В TurboBasic я это все делал легко. Машины были слабые. Это да. Короче, я эту задачу решил в старом текстовом редакторе "Foton" для DOS. Догадайтесь с одного раза. Как это у меня получилось..."
> Владимир Громов
Теперь по программе:
Хм. Программа явно на правильном пути.
1. Непонятно только с количеством удаляемых обьектов;
2. Непонятно с какой точность должен вводить юзер шаги по X или Y;
3. Непонятен диалог "Укажите точку на обьекте". В моем случае, вообще то,
на одном из чертежей было две параллельных линии отстоящих друг от друга на расстоянии 12 мм.
Это получается два прохода чистить?
Пока все.
Окончательный вариант программы.
Но!
Гражданин Forma должен точно указывать количество рядов, столбцов и расстояния между рядами и столбцами. Если товарищ Forma не знает этих параметров, то вся затея идет коту под хвост. В этом случае господин Forma пусть сам отвечает за возможную потерю данных.
;************** er_ar.lsp ********************************************************* ; erase_array ; Программа, обратная массиву. Стирает объекты с ; заданным расстояниями между рядами и столбцами, ; такими же, которые использовались в массиве. ; Число рядов и столбцов также должно быть таким же, ; какое было в массиве. В противном случае возможна ; неконтролируемая потеря объектов. ; Разработал Владимир Громов. ; (defun C:ER_AR ( / ss pob ob ny nx sy sx poy) (setvar "CMDECHO" 0) (setq ss (entsel "\n Выберите объект: ")) (setq pob (cadr ss)) (setq ob (car ss)) (setq ny (getint "\n Число рядов (---): ")) (setq nx (getint "\n Число столбцов (|||): ")) (setq sy (getint "\n Расстояние между рядами (---): ")) (setq sx (getint "\n Расстояние между столбцами (|||): ")) (setq poy pob) (if pob (progn (command "_COPY" ob "" pob pob) (repeat ny (repeat nx (command "_ERASE" pob "") (setq pob (list (+ (car pob) sx) (cadr pob))) ); repeat (setq pob (list (car poy) (+ (cadr pob) sy))) ); repeat ); progn ); if (princ) )
Возможный макрос для кнопки или пункта меню:
^C^C^P(if (not C:ER_AR) (load "er_ar") ER_AR
> AY
и то правда, совсем забыл. Когда-то на какой-то ветке поговаривали что метки идут с шагом кратным 2 (это я так на всякий случай). А как перевести число в метку и наоборот, если не секрет? Я не програмист, пробывал на прямую RTOS и т.д. - не получается.
> Владимир Громов
А, вот интересно. Все был товарищ Forma.
Сегодня гражданин Forma. К чему бы это? :(
Для проверки своего предложения сделал тестовую функцию которая выделяет примитивы с метками идущими последовательно за меткой выделенного примитива. Тест показывает, что алгоритм вполне жизнеспособен и при доработке вполне может использоваться.
В данной тестовой функции примитивы выбираются только по возрастанию метки поэтому для лучшего эфекта первым следует выбрать примитив наиболее близкий к первой из копий в массиве. Как показывает тест (ACAD 2000) при выполнении команды масив копии выбранных объектов строятся вертикальными рядами поэтому первая копия распологается над(или под) исходными объектами. Отмечу, что выбирать необходимо примитив присутствующий именно в копии потому, что метки исходных объектов никак не связаны копиями.
Кроме того желательно использовать функцию для массивов простых примитивов (не имеющих подпримитивов). Иначе действия не очень предсказумы.
Наличие в копиях по нескольку объектов не должно создавать проблем. Выделение большого количества (~1000) примитивов тоже не состав вляет трудности (зажимешь enter и смотришь как выделяются объекты).
Результат работы - выбранные примитивы с которыми пользователь может обращаться как пожелает.
ПРЕДУПРЕЖДЕНИЕ:
ФУНКЦИЯ СУГУБО ТЕСТОВАЯ И НЕ ДОЛЖНА ПРИМЕНЯТЬСЯ В РАБОЧИХ ЧЕРТЕЖАХ.
ИСПОЛЬЗУЙТЕ ТОЛЬКО В КОПИЯХ!!!
;запуск по TEST2 в комстроке ;выход по Esc (defun hex1+ (str / a one list-new) (setq one t str (reverse (vl-string->list str)) list-new '() ) (while one (setq list-new (cons (cond ((null str) (setq one nil) 49) ((< (setq a (car str)) 57) (setq one nil a (1+ a))) ((= a 57) (setq one nil a 65 )) ((< a 70) (setq one nil a (1+ a))) (t (setq a 48)) ) list-new ) str (cdr str) ) ) (vl-list->string (append (reverse str) list-new)) ) (defun c:test2 (/ hen ss) (setq hen (cdr (assoc 5 (entget (car (entsel))))) ss (ssadd) ) (ssadd (handent hen ) ss) (sssetfirst nil ss) (while t (getstring "\n To continue press ENTER, to exit press ESC: ") (ssadd (handent (setq hen (hex1+ hen))) ss) (sssetfirst nil ss) ) )
Хотелось бы услышать отзывы.
> Forma
Да, ну, шутка, сегодня все сразу. Я постарался сделать программу именно по типу "_-ARRAY" ("-МАССИВ") для прямоугольного массива. Что она там будет удалять, если расстояния будут взяты с потолка, не берусь судить. Лучше, наверное, на время выполнения программы отключать привязки. Число рядов и столбцов, в принципе, могут быть достаточно большими, даже превышать реальные, все равно программа работает. Конечно, основная опасность в том, что могут быть удалены нужные объекты, но тут я ничего не могу поделать.
> AY
Мне трудно тестировать две программы по одной задаче, но тем не менее попробую.
Сразу вопрос. По какой команде она запускается?
> Forma
TEST2 в начале кода написано, будте внимательны.
> Владимир Громов
Программа работает. Но как еще до конца непонятно для меня. Давайте по шагам.
Вопрос. С какой точностью юзер должен задавать шаг? Например: Обьекты на чертеже расположены с шагом 20.15 мм.
> AY
Сделал массив из 100 объектов (10x10) и запустил test2. Объекты выделяются по порядку, но пришлось нажимать Enter 100 раз. Может, выделить сразу все объекты?
> AY
Первое запустил программу, заселектировал обьект, дальше Enter и ничего;
Второе. Я приношу извинения, но не могу тестировать две программы. Я дело это все во время работы. Не справляюсь:(
> Forma
Для меня непривычны такие размеры (десятые и сотые доли мм), поэтому в программе задаются целые числа, но можно поменять функцию для ввода расстояний.
;************** er_ar.lsp ********************************************************* ; erase_array ; Программа, обратная массиву. Стирает объекты с ; заданным расстояниями между рядами и столбцами, ; такими же, которые использовались в массиве. ; Число рядов и столбцов также должно быть таким же, ; какое было в массиве. В противном случае возможна ; неконтролируемая потеря объектов. ; Разработал Владимир Громов. ; (defun C:ER_AR ( / ss pob ob ny nx sy sx poy) (setvar "CMDECHO" 0) (setq ss (entsel "\n Выберите объект: ")) (setq pob (cadr ss)) (setq ob (car ss)) (setq ny (getint "\n Число рядов (---): ")) (setq nx (getint "\n Число столбцов (|||): ")) (setq sy (getreal "\n Расстояние между рядами (---): ")) (setq sx (getreal "\n Расстояние между столбцами (|||): ")) (setq poy pob) (if pob (progn (command "_COPY" ob "" pob pob) (repeat ny (repeat nx (command "_ERASE" pob "") (setq pob (list (+ (car pob) sx) (cadr pob))) ); repeat (setq pob (list (car poy) (+ (cadr pob) sy))) ); repeat ); progn ); if (princ) )
Возможный макрос для кнопки или пункта меню:
^C^C^P(if (not C:ER_AR) (load "er_ar") ER_AR
Объекты для удаления выбираются по одному. То есть, если есть 2 параллельные линии и они размножены в массив, то надо сначала выполнить команду с одной линией, а потом с другой. Но начальный объект остается.
Может, выделить сразу все объекты?
Есть проблемы с определением последнего примитива особенно если не известно: 1) количество копий; 2) с какого примитива начат отсчет; 3) колличество примитивов в исходном наборе; 4) присутствие составных примитивов. Поэтому и сделано так что бы пользователь определял окончание визуально.
По поводу 100 раз нажать - я же писал, что можно зажать клавишу и подержать пару сек.
> Runa
Перевод метки в число недавно давал А.Ривилис в теме о вставке поля.
Форум работает на PunBB, при поддержке Informer Technologies, Inc