ADN Club > AutoLisp / VisualLISP и DCL
Макрос для измерения длины, высоты и площади фасадов, зашитых в блок
Алексей Кулик:
У меня не с модификации, у меня с логики и общего подхода претензии :) Форматирование я уже переделал в VLIDE:
--- Код - Auto/Visual Lisp [Выбрать] ---(vl-load-com)(defun c:sv_tabl (/ alltext _textfind _textfor kscale _block _name_fas minpoint_l maxpoint_l minpoint_h maxpoint_h diff_l diff_h _sum _sum_sq _visible bum bum_set bum_list quan fewlines cho num ) (setvar "Peditaccept" 1) (setq _sum 0.0) (setq _sum_sq 0.0) (setq alltext (ssget "_X" (list (cons 1 "*00 }") (cons 0 "Mtext")))) (setq _textfind (vlax-ename->vla-object (ssname alltext 0))) (setq _textfor (vla-get-textstring _textfind)) (if (wcmatch _textfor "*100 }") (setq kscale 0.01) (setq kscale 0.02) ) ;_ end of if (setq _acad (vlax-get-acad-object)) (setq active_doc (vla-get-activedocument _acad)) (setq m_space (vla-get-modelspace active_doc)) (setq _blockselect (ssget "_X" (list (cons 8 "_АХП_Фасад") (cons 0 "Insert")))) (setq counter 0) (princ (strcat "Найдено блоков:" (rtos (sslength _blockselect) 2 0) "шт.")) (terpri) (while (< counter (sslength _blockselect)) (setq _block (vlax-ename->vla-object (ssname _blockselect counter))) (setq _name_fas (vla-get-effectivename _block)) (vla-getboundingbox _block 'minpoint 'maxpoint) (setq minpoint_l (nth 0 (vlax-safearray->list minpoint))) (setq maxpoint_l (nth 0 (vlax-safearray->list maxpoint))) (setq minpoint_h (nth 1 (vlax-safearray->list minpoint))) (setq maxpoint_h (nth 1 (vlax-safearray->list maxpoint))) (setq diff_l (* kscale 10 (- maxpoint_l minpoint_l))) (setq diff_h (* kscale 10 (- maxpoint_h minpoint_h))) (setq l (rtos diff_l 2 1)) (princ (strcat "Длина " _name_fas ":" l "м")) (setq _visible (vlax-invoke _block 'getdynamicblockproperties)) (nth 0 _visible) (vla-put-value (nth 0 _visible) (vlax-make-variant "контур" (vlax-variant-type (vla-get-value (nth 0 _visible)))) ) ;_ end of vla-put-value (terpri) (command "_.bedit" _name_fas) (setq cho (ssget "_X" (list (cons 0 "Spline")))) (if cho (progn (setq num (sslength cho)) (repeat num (command "_.splinedit" cho "_P" "25")) (princ (strcat "Преобразовано в полилинии" (rtos num 2 0) "сплайнов")) ) ;_ end of progn (princ "Не найдены сплайны") ) ;_ end of if (command "_bclose" "_s") (setq bum (vla-explode _block)) (setq bum_list (vlax-safearray->list (vlax-variant-value bum))) (setq quan (vl-list-length bum_list)) (if (= quan 1) (progn (setq sq_a (vlax-get-property (vlax-ename->vla-object (entlast)) 'area))) (progn (setq ss (ssadd)) (setq bum_set (foreach x bum_list (ssadd (vlax-vla-object->ename x) ss))) (setq fewlines (command "_pedit" "_M" bum_set "" "_J" "_J" "_B" "100" "_X")) (setq sq_a (* kscale (vlax-get-property (vlax-ename->vla-object (entlast)) 'area))) (if (< sq_a 1) (progn (setq sq_a (* kscale (vlax-get-property (vlax-ename->vla-object (entlast)) 'area))) ) ;_ end of progn ) ;_ end of if ) ;_ end of progn ) ;_ end of if (princ (strcat "Площадь:" (rtos sq_a 2 1) " м2")) (terpri) (vla-erase (vlax-ename->vla-object (entlast))) (setq _table (ssget "_X" (list (cons 1 (strcat "Характеристика здания (" _name_fas ") ")) (cons 0 "ACAD_TABLE")))) (setq _t (vlax-ename->vla-object (ssname _table 0))) (vla-settext _t 3 1 l) (vla-settext _t 1 1 (rtos diff_h 2 1)) (vla-settext _t 2 1 (rtos sq_a 2 1)) (setq _sum (+ _sum diff_l)) (setq _sum_sq (+ _sum_sq sq_a)) (vla-put-value (nth 0 _visible) (vlax-make-variant "фасад" (vlax-variant-type (vla-get-value (nth 0 _visible)))) ) ;_ end of vla-put-value (setq counter (+ counter 1)) ) ;_ end of while (princ (strcat "\nСуммарная длина фасадов:" (rtos _sum 2 1) "м")) (princ (strcat "\nСуммарная площадь фасадов:" (rtos _sum_sq 2 1) "м2")) (terpri) (setq a (rtos _sum 2 1)) (setq b (rtos _sum_sq 2 1)) (setq _tablex (ssget "_X" (list (cons 1 "Характеристика зданий") (cons 0 "ACAD_TABLE")))) (setq _t (vlax-ename->vla-object (ssname _tablex 0))) (vla-settext _t 2 1 a) (vla-settext _t 1 1 b) (setvar "Peditaccept" 0) ) ;_ end of defunПока подожду реакции автора ;)
Peacemaker_kiss:
--- Цитата: Алексей Кулик от 01-12-2014, 21:04:21 ---Скажу честно: мне не очень понятна такая дикая необходимость использования команд; зачем редактировать блок, если его потом все равно разбиваешь.
--- Конец цитаты ---
Я в преамбуле указал, что я недостаточно знаю как работать со списками, мне проще с объектами, поэтому я добавил пояснения к макросу, почитай их, вдруг идеи возникнут, как мне условие проверки списка на наличии слайна в нем сформировать
Peacemaker_kiss:
--- Цитата: Александр Ривилис от 01-12-2014, 21:07:18 ---P.S.: Я бы начал с критики форматирования кода, ибо не смог его прочитать.
--- Конец цитаты ---
Алексей отформатировал, я примечания выполнил к макросу, очень жду критики!!!!! Учиться хочу!!!!!
Peacemaker_kiss:
--- Цитата: Алексей Кулик от 01-12-2014, 21:04:21 ---P.S. Критику кода примешь?
--- Конец цитаты ---
Не то слово, почту за честь
Алексей Кулик:
Ок, погнали :) Перечислил то, что увидел. Возможно, еще наберется ;)
1. Нет меток начала и конца отмены.
2. Не обрабатываются варианты блокирования / заморозки слоев
3. Ты абсолютно уверен, что текст с указанием масштаба будет один? А если не один, то первый гарантированно указывает на масштаб (забудем про то, что чертить в ACAD с масштабом - вообще нонсенс, ну да ладно)?
4. Ты уверен, что в дин.блоке фасада обязательно будет видимость "Контур"?
5. vla-explode возвращает variant-массив получившихся объектов. Преобразовывай в список и обрабатывай.
6. Не возвращается обратно видимость обработанного блока
7. Ты слишком уверен, что таблица опять же:
а) существует в файле
б) она именно такого вида, как должно быть
в) и она только одна.
8. Ты так лихо устанавливаешь peditaccept в 1... А если у пользователя она была установлена в 0?
9. Ты с легкостью используешь splinedit, но напрочь забыл про plineconvertmode и delobj.
10. Нет обработчика ошибок (ну это так, до кучи)
11. pedit в твоем варианте, думаю, можно будет заменить чисто программной обработкой: получить координаты каждой полилинии, при необходимости выполнить реверс (см. pltools с dwg.ru), на их основе построить новую полилинию и забрать с нее площадь. Или набор сплайнов / полилиний преобразовать в Region, получить площадь и удалить созданный объект.
P.S. Я думал было написать код, но времени не хватило. А показывать сырые поделки (которые вдобавок не работают) - никуда не годится. Так что все "насухую".
Навигация
Перейти к полной версии