Re: LISP. Подсчет длины линий на определенном слое

> Pave1
Люблю я похвалы smile
Спасибо!
Лови до кучи с запросом маштаба (коэффициента)...

(defun c:mlen3 (/ m)
  (vl-load-com)
  (setq m (getreal "\nвведите маштабный коэффициент:\t"))
  (princ "\n\n  Общая длинна всех линейных примитивов по слоям:")
  (mlen3_1 t)
  (princ)
) ;_  defun
(defun mlen3_1 (i)
  (if (setq i (tblnext "LAYER" i))
    (progn
      (mlen3_2 (cdadr i))
      (mlen3_1 nil)
    ) ;_  progn
  ) ;_  if
) ;_  defun
(defun mlen3_2 (lay / SS SUM_LEN)
  (if (setq
    sum_len    0.
    ss    (ssget "_X" (list (cons 8 lay)))
      ) ;_  setq
    (foreach item (mapcar
            (function vlax-ename->vla-object)
            (vl-remove-if
              (function listp)
              (mapcar
            (function cadr)
            (ssnamex ss)
              ) ;_  mapcar
            ) ;_ vl-remove-if
          ) ;_  mapcar
      (setq
    sum_len    (+ sum_len
           (if (vlax-property-available-p item 'length)
             (vla-get-length item)
             (cond
               ((=
              (strcase (vla-get-objectname item) t)
              "acdbarc"
            ) ;_  =
            (vla-get-arclength item)
               )
               ((=
              (strcase (vla-get-objectname item) t)
              "acbcircle"
            ) ;_  =
            (* pi 2.0 (vla-get-radius item))
               )
               (t 0.0)
             ) ;_  cond
           ) ;_  if
        ) ;_  +
      ) ;_  setq
    ) ;_  foreach
  ) ;_  if
  (princ (strcat "\n\t" lay " = " (rtos (* sum_len m) 2 4)))
) ;_  defun

Re: LISP. Подсчет длины линий на определенном слое

Евгений!
Слишком сладко - тоже плохо.
И только по этой причине я больше не буду хвалить тебя :)

Re: LISP. Подсчет длины линий на определенном слое

> Pave1
Так мне и надо!
Больше не буду писать никому не нужные программы...

Re: LISP. Подсчет длины линий на определенном слое

> Евгений Елпанов
Не силен в лиспе и только начинаю пользоваться его прелестями, поэтому вопрос, код который вы привели, надо сохранить в файл с именем vl-load-com.lsp, загрузить его appload и вызывать (vl-load-com)???

Re: LISP. Подсчет длины линий на определенном слое

Боже, как я глуп, mlen3...

Re: LISP. Подсчет длины линий на определенном слое

spasibo ogromnoje!!!

Re: LISP. Подсчет длины линий на определенном слое

> Aleksiej
Пригодилось?

Re: LISP. Подсчет длины линий на определенном слое

Нужна программка для подсчёта длин выделенных полилиний с сортировкой по типам и желательно с записью в файл.
Помогите пожалуйста!

Re: LISP. Подсчет длины линий на определенном слое

Эх, если бы еще программка Евгения (2-й пост) еще и полилинии вдобавок считала, вообще бы замечательно было ....

Re: LISP. Подсчет длины линий на определенном слое

> vvp
Нет ничего проще...

(defun calc_dist (/ sset)
(vl-load-com)
(if (setq
sset (ssget "_x"
(list '(0 . "LINE,*POLYLINE")
(assoc 8 (entget (car (entsel "\nSelect layer object:")))))))
(princ (strcat "\nLength — "
(rtos(apply (function +)
(mapcar (function
(lambda (e) (vla-get-Length (vlax-ename->vla-object e))))
(vl-remove-if (function listp)
(mapcar (function cadr) (ssnamex sset))))))))))

Re: LISP. Подсчет длины линий на определенном слое

> Евгений Елпанов
Понял свою ошибку - перед pline звездочку не поставил.
Благодарю !

Re: LISP. Подсчет длины линий на определенном слое

В архиве этого форума лежала самая универсальная прога для всех версий акада. Суммировала полилинии. Я еще добавил отрезки, дуги и круги. Вроде работает.
(defun c:dlina(/ nab PER i kol B lin n)
(setvar "cmdecho" 0)
(setq nab (ssget))
(setq PER 0.00)
(setq i 0)
(setq kol (sslength nab))
(while (< i kol)
        (setq B (ssname nab i))
        (setq lin (entget B))
        (cond ((OR (= (cdr(assoc 0 lin)) "LWPOLYLINE")
                   (= (cdr(assoc 0 lin)) "CIRCLE"))
               (command "_area" "_o" B)
               (setq PER (+ PER (getvar "perimeter"))))
              ((= (cdr(assoc 0 lin)) "LINE")
               (setq PER (+ PER (distance (cdr(assoc 10 lin)) (cdr(assoc 11 lin))))))
              ((= (cdr(assoc 0 lin)) "ARC")
               (setq n (- (cdr(assoc 51 lin)) (cdr(assoc 50 lin)))
                     n (if (< n 0) (+ (* 2 pi) n) n)
                     PER (+ PER (* (cdr(assoc 40 lin)) n))))
        )
        (setq i (1+ i)))
(prompt "\n Длина=")
(prin1 PER)
(setvar "cmdecho" 1))

Re: LISP. Подсчет длины линий на определенном слое

Добавлю и я свой код. Он суммирует длины выделенных объектов. Возможно установить масштабный коэффициент.
Реализован на основе miscellaneous реактора. Достаточно просто загрузить код.
Как сохранить программный код на своем компьютере

(vl-load-com)
(if (null *MIP-MODEMACRO-HTXT*)(setq *MIP-MODEMACRO-HTXT* 3.0)) ;_Высота текста
(if (null *MIP-MODEMACRO-RTOS*)(setq *MIP-MODEMACRO-RTOS* -1.0));_Округление -1-LUPREC
(VL-PROPAGATE '*MIP-MODEMACRO-HTXT*)
(VL-PROPAGATE '*MIP-MODEMACRO-RTOS*)
;;=============== Реакторы =======================
(if *vlr-mis* (progn(setq *vlr-mis* nil)
(vlr-remove-all :vlr-miscellaneous-reactor)))
(if (not *vlr-mis*)
(setq   *vlr-mis* (vlr-miscellaneous-reactor nil
'((:vlr-pickfirstmodified . selchange)))))
(defun selchange (reactor event / selset sum_len item_name nstyle err len ent ds)
  (if (null *MIP-MODEMACRO-OLD*)(setq *MIP-MODEMACRO-OLD* (getvar "MODEMACRO")))
  (setq sum_len 0.0)
  (setq err (vl-catch-all-apply '(lambda ()(and (setq selset   (vla-get-pickfirstselectionset
           (vla-get-activedocument (vlax-get-acad-object))))
      (> (vla-get-count selset) 0)))))
  (if (and (not (vl-catch-all-error-p err)) err)
  (progn
   (vlax-for   item selset
    (cond((= (strcase (vla-get-objectname item)) "ACDBMLINE")
      (setq ent (entget(vlax-vla-object->ename item)))
      (setq len (mapcar 'cdr (vl-remove-if-not (function (lambda (x) (= 11 (car x)))) ent)))
      (if (= 2 (logand 2 (cdr(assoc 71 ent))))(setq len (append len (list (car len)))))
      (setq ds (car len))
          (setq sum_len (+ sum_len (apply '+ (mapcar '(lambda(x / dst)(setq dst (distance ds x))(setq ds x) dst) len)))))
         ((vlax-property-available-p item 'length)
        (setq sum_len (+ sum_len (if (VL-CATCH-ALL-ERROR-P(VL-CATCH-ALL-APPLY '(lambda()(setq len (vla-get-length item))))) 0 len)))
            (setq   item_name (strcase (vla-get-objectname item) t)
                    sum_len (+ sum_len
                                (cond ((= item_name "acdbcircle")(* 2 pi (vla-get-radius item)))
                                      ((= item_name "acdbarc")(vla-get-ArcLength item))
                                      ((member item_name '("acdbellipse" "acdbspline"))
                                       (vlax-curve-getDistAtParam item (vlax-curve-getEndParam item)))
                       (t 0.0)))))
     (t nil))) ;_ end of vlax-for
   (if (member (type *MIP-MODEMACRO-SCALE*) '(INT REAL))(progn
   (setq item_name (strcat " (K=" (VL-PRINC-TO-STRING *MIP-MODEMACRO-SCALE*) ")"))
   (setq sum_len (* sum_len *MIP-MODEMACRO-SCALE*)))
   (setq item_name " (K=1)" *MIP-MODEMACRO-SCALE* 1))
   (setq *MIP-LENGTH* sum_len)(setvar "modemacro" (strcat "Выбрано="
   (itoa (vla-get-count selset))  " Длина="
   (rtos sum_len 2 (if (< *MIP-MODEMACRO-RTOS* 0)(getvar "LUPREC") *MIP-MODEMACRO-RTOS*))
   (strcat item_name " MM-масштаб LP-печать")))) ;_ end of progn
   (progn (setvar "modemacro" (if (= (type *MIP-MODEMACRO-OLD*) 'STR) *MIP-MODEMACRO-OLD* ""))
    (if (wcmatch (getvar "modemacro") "Выбрано=*")(setvar "modemacro" ""))
      (setq *MIP-MODEMACRO-OLD* nil))))
(defun c:MM ( / buf )(initget 7)
  (setq *MIP-MODEMACRO-SCALE* (getreal "\nНовый масштабный коэффициент: "))
  (initget 6)(princ "\nВысота текста <")(princ *MIP-MODEMACRO-HTXT*)(princ ">: ")
  (if (setq buf (getdist))(setq *MIP-MODEMACRO-HTXT* buf))
  (initget 4 "L")(princ "\nТочность округления [Luprec] <")
  (if (< *MIP-MODEMACRO-RTOS* 0)(princ "Luprec")(princ *MIP-MODEMACRO-RTOS*))
  (princ ">: ")
  (if (setq buf (getint))(setq *MIP-MODEMACRO-RTOS* (if (numberp buf) buf -1)))
  (VL-PROPAGATE '*MIP-MODEMACRO-HTXT*)(VL-PROPAGATE '*MIP-MODEMACRO-RTOS*)
  (VL-PROPAGATE '*MIP-MODEMACRO-SCALE*)(princ))
(defun C:MC ()(setvar "modemacro" "")(princ))
(defun c:LP ( )(if (= (type *MIP-LENGTH*) 'REAL)(progn
(vla-addtext(vla-get-block(vla-get-ActiveLayout(vla-get-ActiveDocument(vlax-get-acad-object))))
(rtos *MIP-LENGTH* 2 (if (< *MIP-MODEMACRO-RTOS* 0)(getvar "LUPREC") *MIP-MODEMACRO-RTOS*))
(vlax-3d-point '(0 0 0)) *MIP-MODEMACRO-HTXT*)(princ "\n Укажите точку вставки текста:")
(command "_.copybase" '(0 0 0) (entlast) "" "_.erase" (entlast) "" "_.pasteclip" pause)))
(princ))

Описание
При предварительном выделении объектов в поле MODEMACRO будет писаться кол-во, длина выделенных объектов и масштабный коэффициент.
Суммируются длины MLINE по точкам выравнивания
Определены 3 команды.
MM - Задание установок (Масштабный коэффициент, точность округления, высота текста)
MC - Modemacro clear - очистить Modemacro (Тьфу-тьфу, пока необходимости небыло)
LP - Length Print - печать подсчитанной длины.

Re: LISP. Подсчет длины линий на определенном слое

неработает

Re: LISP. Подсчет длины линий на определенном слое

Всем привет!!!
Kpblc спасибо за лисп mlen2, а также огромное спасибо Евгению Елпанову за лисп mlen3.
На данный момент я работаю программой mlen2, потому что я выбираю сначала слой, который мне нужен и затем – выбираю «Рамкой-секрамкой» все примитивы на плане, это очень удобно, но не удобно каждый раз выбирать новый слой.
Программа mlen3  Евгения Елпанова тоже хорошая программа – но, когда на чертеже один план (вид, разрез и т.д.) и программа считает ВСЕ примитивы в слое и всего чертежа!!!!!! Если я инженер по проектированию систем пожаротушения – нет смысла считать длины, например слой «стена», «фасад» и т.д. (10-15 шт и более слоев). И у меня на чертеже – несколько планов , разрезов и т.д. Мне не надо чтоб считала ВСЕ, а именно , то что мне нужно!
В целом задумка очень хорошая!
Kpblc и Евгений Елпанов  можно как-то объединить две программы?
Чтоб программа:
- дала возможность пользователю выбрать объекты (Рамкой , секрамкой и т.д.);
- считала и составляла список только включенных и разблокированных слоёв.
Спасибо. Джек.

Re: LISP. Подсчет длины линий на определенном слое

> Dextron3
Очень лаконично. Твой компьютер не работает?

> Джек
Продолжение mlen3 Евгения Елпанова. Считает длину выбранных примитивов с учетом масштабного коэффициента, с сортировкой по слоям. Выключенные, заблокированные слои игнорируются.

;Команда MLEN4
(defun c:mlen4 (/ m ss clist temp)
  (defun sort (lst predicate)
    (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst predicate))
  )
  (defun combine (inlist is-greater is-equal / sorted current result)
    (setq sorted (sort inlist is-greater))
    (setq current (list (car sorted)))
    (foreach item (cdr sorted)
      (if (apply is-equal (list item (car current)))
    (setq current (cons item current))
    (progn
      (setq result (cons current result))
      (setq current (list item))
    )
      )
    )
    (cons current result)
  )
  (defun mlen3_1 (lst / sum_len)
    (setq sum_len 0)
    (foreach item (mapcar 'car lst)
      (setq
    sum_len    (+ sum_len
           (if (vlax-property-available-p item 'length)
             (vla-get-length item)
             (cond
               ((=
              (strcase (vla-get-objectname item) t)
              "acdbarc"
            ) ;_  =
            (vla-get-arclength item)
               )
               ((=
              (strcase (vla-get-objectname item) t)
              "acbcircle"
            ) ;_  =
            (* pi 2.0 (vla-get-radius item))
               )
               (t 0.0)
             ) ;_  cond
           ) ;_  if
        ) ;_  +
      )
    )
    (if    (not (zerop sum_len))
      (princ
    (strcat "\n\t" (cdadr lst) " = " (rtos (* sum_len m) 2 4))
      )
    )
  )
  (vl-load-com)
  (and
    (setq m (getreal "\nвведите маштабный коэффициент:\t"))
    (setq ss (ssget "_:L"))
    (setq ss (mapcar
           (function vlax-ename->vla-object)
           (vl-remove-if
         (function listp)
         (mapcar
           (function cadr)
           (ssnamex ss)
         ) ;_  mapcar
           ) ;_ vl-remove-if
         )
    )
    (mapcar '(lambda (x)
           (setq temp (cons (cons x (vla-get-Layer x)) temp))
         )
        ss
    )
    (setq clist    (combine temp
             '(lambda (a b)
                (> (cdr a) (cdr b))
              )
             '(lambda (a b)
                (eq (cdr a) (cdr b))
              )
        )
    )
    (princ
      "\n\n  Общая длинна всех линейных примитивов по слоям:"
    )
    (mapcar 'mlen3_1 clist)
  )
  (princ)
) ;_  defun

Re: LISP. Подсчет длины линий на определенном слое

Ура!!!!!
То что я хотел!!!!!!
VVA спасибо тебе огромное!!!!!

Re: LISP. Подсчет длины линий на определенном слое

VVA я тут программу по корректировал под себя

;Команда MLEN4
(defun c:mlen4-1 (/ m ss clist temp)
  (defun sort (lst predicate)
    (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst predicate))
  )
  (defun combine (inlist is-greater is-equal / sorted current result)
    (setq sorted (sort inlist is-greater))
    (setq current (list (car sorted)))
    (foreach item (cdr sorted)
      (if (apply is-equal (list item (car current)))
  (setq current (cons item current))
  (progn
    (setq result (cons current result))
    (setq current (list item))
  )
      )
    )
    (cons current result)
  )
  (defun mlen3_1 (lst / sum_len)
    (setq sum_len 0)
    (foreach item (mapcar 'car lst)
      (setq
  sum_len  (+ sum_len
       (if (vlax-property-available-p item 'length)
         (vla-get-length item)
         (cond
           ((=
        (strcase (vla-get-objectname item) t)
        "acdbarc"
      ) ;_  =
      (vla-get-arclength item)
           )
           ((=
        (strcase (vla-get-objectname item) t)
        "acbcircle"
      ) ;_  =
      (* pi 2.0 (vla-get-radius item))
           )
           (t 0.0)
         ) ;_  cond
       ) ;_  if
    ) ;_  +
      )
    )
    (if  (not (zerop sum_len))
      (princ
  (strcat "\n\n" (cdadr lst) " = " (rtos (* sum_len m) 2 2) "мм" " или "
          (rtos (/ (* sum_len m)1000.0) 2 2) "м" "\n(к=1,1 ~ "
          (rtos (* 1.1 (/ (* sum_len m)1000.0)) 2 2) "м)")
      )
    )
  )
  (vl-load-com)
  (and
    (setq m (getvar "DIMLFAC"))
    (setq ss (ssget "_:L"))
    (setq ss (mapcar
         (function vlax-ename->vla-object)
         (vl-remove-if
     (function listp)
     (mapcar
       (function cadr)
       (ssnamex ss)
     ) ;_  mapcar
         ) ;_ vl-remove-if
       )
    )
    (mapcar '(lambda (x)
         (setq temp (cons (cons x (vla-get-Layer x)) temp))
       )
      ss
    )
    (setq clist  (combine temp
       '(lambda (a b)
          (> (cdr a) (cdr b))
        )
       '(lambda (a b)
          (eq (cdr a) (cdr b))
        )
    )
    )
    (princ
      (strcat "\n Масштабный коэффициент " (rtos m 2 2)
      "\n\n Общая длинна всех линейных примитивов по слоям: ")
    )
    (mapcar 'mlen3_1 clist)
  )
  (princ)
) ;_  defun

И теперь при создании нового файла и иногда на старом файле автокад выдает ошибку типа
Общая длинна всех линейных примитивов по слоям: ; ошибка: неверный тип аргумента: stringp nil
эту ошибку также выдает когда вызываешь программу Mlen4
В чем причина?

Re: LISP. Подсчет длины линий на определенном слое

> Джек
У себя погонял, ошибку не выявил. Пришли на почту файл, в котором она выскакивает. Посмотрю. Правда я тут немного в отпуске ( до 7 июля), тат что ответ может быть с задержкой

Re: LISP. Подсчет длины линий на определенном слое

А можно что либо подобное но для суммирования площадей замкнутых фигур?

Re: LISP. Подсчет длины линий на определенном слое

> Джек
Ошибку нашел. Исправленный вариант

;Команда MLEN4
(defun c:mlen4 (/ m ss clist temp)
  (defun sort (lst predicate)
    (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst predicate))
  )
  (defun combine (inlist is-greater is-equal / sorted current result)
    (setq sorted (sort inlist is-greater))
    (setq current (list (car sorted)))
    (foreach item (cdr sorted)
      (if (apply is-equal (list item (car current)))
  (setq current (cons item current))
  (progn
    (setq result (cons current result))
    (setq current (list item))
  )
      )
    )
    (cons current result)
  )
  (defun mlen3_1 (lst / sum_len)
    (setq sum_len 0)
    (foreach item (mapcar 'car lst)
      (setq
  sum_len  (+ sum_len
       (if (vlax-property-available-p item 'length)
         (vla-get-length item)
         (cond
           ((=
        (strcase (vla-get-objectname item) t)
        "acdbarc"
      ) ;_  =
      (vla-get-arclength item)
           )
           ((=
        (strcase (vla-get-objectname item) t)
        "acbcircle"
      ) ;_  =
      (* pi 2.0 (vla-get-radius item))
           )
           (t 0.0)
         ) ;_  cond
       ) ;_  if
    ) ;_  +
      )
    )
    (if  (not (zerop sum_len))
      (princ
  (strcat "\n\t" (cdar lst) " = " (rtos (* sum_len m) 2 4))
      )
    )
  )
  (vl-load-com)
  (and
    (setq m (getreal "\nвведите маштабный коэффициент:\t"))
    (setq ss (ssget "_:L"))
    (setq ss (mapcar
         (function vlax-ename->vla-object)
         (vl-remove-if
     (function listp)
     (mapcar
       (function cadr)
       (ssnamex ss)
     ) ;_  mapcar
         ) ;_ vl-remove-if
       )
    )
    (mapcar '(lambda (x)
         (setq temp (cons (cons x (vla-get-Layer x)) temp))
       )
      ss
    )
    (setq clist  (combine temp
       '(lambda (a b)
          (> (cdr a) (cdr b))
        )
       '(lambda (a b)
          (eq (cdr a) (cdr b))
        )
    )
    )
    (princ
      "\n\n  Общая длинна всех линейных примитивов по слоям:"
    )
    (mapcar 'mlen3_1 clist)
  )
  (princ)
) ;_  defun

В этом куске кода

(if  (not (zerop sum_len))
      (princ
  (strcat "\n\t" (cdadr lst) " = " (rtos (* sum_len m) 2 4))
      )
    )

вместо cdadr надо cdar

Re: LISP. Подсчет длины линий на определенном слое

> Valery Brelovsky
Вариант программы здесь
https://www.caduser.ru/forum/topic19748.html
Мне кажется та тема больше подходит

Re: LISP. Подсчет длины линий на определенном слое

VVA (2007-06-27 16:01:31)
Спасибо Вам. Поиск ни чего не дал. Но потом увидел чуть ниже вот эту тему. Это решило мою проблему.
"ObjectARX. GeomProps — площадь, длина, объем выбранных примитивов"
https://www.caduser.ru/forum/topic36136.html

Re: LISP. Подсчет длины линий на определенном слое

VVA спасибо тебе большое!!!!
РАБОТАЕТ!!!!

Re: LISP. Подсчет длины линий на определенном слое

Программа Mlen4 хорошая, а можно сделать чтобы результат выдавался на рабочий стол, в виде таблицы?