Тема: Как программно измерить длину труб в 3D-чертеже?

Люди, помогите!!
Я нашел как рисовать 3D трубы с помощью ЛИПСа
https://www.caduser.ru/forum/topic21092.html
, но задача в другом. Как в нарисованном файле измерить трубопроводы, которые уже нарисованны?
Может, кто-то знает?
Заранее благодарен!!!

Re: Как программно измерить длину труб в 3D-чертеже?

> Виталий
Если они не объединены (union) в общий солид
думаю нужно копать в направлении GetBoundingbox
а потом вытаскивать длину большего ребра
И еще придется выставлять ПСК по объекту
Чисто умозрительно, может, и заблуждаюсь...
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

Не чего не понял, но для обсуждения кладу файлик Pipe_long_calc.dwg по адресу
http://dwg.ru/dwl/index.php?id=639

Re: Как программно измерить длину труб в 3D-чертеже?

> Виталий
Я не знаю какой вы программой пользовались, но как пить дать программа рисует окружность и её выдавливает вдоль трактории(поправьте если я не прав). Так траекторию(линии, полинии и т.д) просто удалять не надо, а преводить скажем на слой defpoint(чтоб не печаталось). А подсчитать длину выупомянутых примитивов несложно.
Я вижу такой путь решения.

Re: Как программно измерить длину труб в 3D-чертеже?

> Виталий
Чё-то не нашел файла
отвечают: Позиция не найдена
:(
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

А если направляющие уже удалены, то длину прямолинейных участков можно подсчитать так
насчет колен придумай сам

;аргументы:
;dia1 - наружный диаметр
;dia2  - иунутренний диаметр
(defun pipl (dia1 dia2 / adoc axss dia len_list)
    (vl-load-com)
   (setq    adoc (vla-get-activedocument
           (vlax-get-acad-object)
         )
  )
  (if (ssget (list (cons 0 "3DSOLID")))
    (progn
      (setq rad1 (/ dia1 2)
        rad2 (/ dia2 2)
        sv (- (* pi (expt rad1 2))(* pi (expt rad2 2))))
      (setq axss (vla-get-activeselectionset adoc))
      (vlax-for a axss
    (setq len_list (cons (/ (vlax-get a 'Volume) sv) len_list)))))
  (apply '+ len_list)
  )
;Вызов :
(setq pipe_length (pipl dia1 dia2))

~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

Олег,
Пробую просчитать длину труб из файлика Pipe_long_calc.dwg по адресу
http://dwg.ru/dwl/index.php?id=639
Autocad выдает
; error: bad argument type: numberp: nil
Может я чето делаю не так, так, как при загрузке Липса программа не спрашивает ввода диаметров...
Что делать, подскажите

Re: Как программно измерить длину труб в 3D-чертеже?

Че то действительно нет файлика по вышеизложенному адресу, поэтому кладу его еще раз по:
Информация будет проверена администратором.
Просмотреть введенные данные: http://dwg.ru/dwl/index.php?id=643

Re: Как программно измерить длину труб в 3D-чертеже?

> Виталий
Позиция не найдена...
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

> Олег(jr.)
Чето действительно нет файлика, тогда вопрос...
Могу ли я отправить файлик на твое мыло?

Re: Как программно измерить длину труб в 3D-чертеже?

> Олег(jr.)
Я отрправил файлик тебе по почте, надеюсь это сможет прояснить суть вопроса:)

Re: Как программно измерить длину труб в 3D-чертеже?

> Виталий
Ну для конкретного файлика - конкретный лиспил:

(defun total-pipe-length (/ acsp adoc axss dia1 dia2 ll
              pt_list rad1 rad2 sum_volume
              sv total_length total_volume
              unit_volume ur)
  (vl-load-com)
  (setq    adoc (vla-get-activedocument
           (vlax-get-acad-object)
         )
  )
  (if (and
    (= (getvar "tilemode") 0)
    (= (getvar "cvport") 1)
      )
    (setq acsp (vla-get-paperspace adoc))
    (setq acsp (vla-get-modelspace adoc))
  )
(setq dia1 89. dia2 76.); в миллиметрах
       (setq rad1 (/ dia1 2 1000);  в метрах
         rad2 (/ dia2 2 1000);  в метрах
        sv (* pi (- (expt rad1 2)(expt rad2 2)))); в кв. метрах
(setq unit_volume sv); объем погонного метра трубы в куб. метрах
(ssget "_X" (list (cons 0 "3DSOLID")))
(setq axss (vla-get-activeselectionset adoc)
      sum_volume 0.)
(vlax-for a axss
  (vla-getboundingbox a 'll 'ur)
  (setq ll (vlax-safearray->list ll)
    ur (vlax-safearray->list ur))
  (setq pt_list (cons ll (cons ur pt_list)))
  (setq sum_volume (+ sum_volume (vlax-get a 'Volume)))); в куб. миллиметрах
  (setq sum_volume (/ sum_volume 1e+009)); в куб. метрах
  (setq total_length (/ sum_volume unit_volume));  в метрах
(vla-clear axss)
(vla-delete axss)
(vlax-release-object axss)
(setq total_length (/ sum_volume unit_volume));в метрах
(alert (strcat "Total: \n" (rtos ( / total_length) 2 2) " meters"))
  )
;Вызов :
(setq sum_pipes_length (total-pipe-length))

~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

> Олег(jr.)
Все очень класно считает, огромное спасибо!
Не сочтите за нахальство, но можно ли прописать в эту в программу, что необходимо указывать диаметр труб и выделять необходимые трубопроводы?
Что имеется ввиду - имеется чертеж линии с трубопроводами разных диаметров. Все трубопроводы на разных слоях. Включаешь один слой, запускаешь липс, выделяешь трубопроводы, и программа выдает длинну труб.
Далее включаешь другой слой, предварительно отключив предыдущий,запускаешь липс, выделяешь трубопроводы, и программа выдает длинну труб...
В любом случае примного благодарен за помощь!!!

Re: Как программно измерить длину труб в 3D-чертеже?

> Олег(jr.)
Я проверил ЛИПС и выяснил, что Dia2 почемуто в расчетах равна нулю.
Пожайлуста просмотри че там не так.. не высчитывает правильное сечение трубы.

Re: Как программно измерить длину труб в 3D-чертеже?

> Vitaliy
Обнаружил грубую ошибку (вставил целый кусок
из предыдущей программы)
В ближайшее время исправлю
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

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

(defun all-layers-by-mask (mask / all_lyrs lyr_list)
  (if mask
  (progn
  (setq all_lyrs (vla-get-layers adoc))
  (vlax-for a all_lyrs
    (if (wcmatch (strcase (vla-get-name a))(strcase (strcat mask "*")))
      (setq lyr_list (cons (vla-get-name a) lyr_list))))
  (acad_strlsort lyr_list))))
(defun get-layer-by-diam (mask diam  / dlyrs)
(foreach i (all-layers-by-mask mask)
  (if (wcmatch (strcase i) (strcase (strcat "*" (itoa diam) "*")))
    (setq dlyrs (cons i dlyrs))))
(acad_strlsort dlyrs))
(defun filter-layer (lname /)
  (list (cons 0 "3DSOLID")(cons 8 lname)))
(defun get-ext-dia (diam)
  (cond
  ((equal diam 10. 0.001) 15.)
  ((equal diam 15. 0.001) 20.)
  ((equal diam 20. 0.001) 25.)
  ((equal diam 25. 0.001) 30.)
  ((equal diam 32. 0.001) 38.)
  ((equal diam 40. 0.001) 45.)
  ((equal diam 50. 0.001) 57.)
  ((equal diam 65. 0.001) 76.)
  ((equal diam 80. 0.001) 89.)
  ((equal diam 100. 0.001) 112.);=>corrected value
  ((equal diam 125. 0.001) 133.)
  ((equal diam 150. 0.001) 159.)
  ((equal diam 200. 0.001) 220.)
  ((equal diam 250. 0.001) 273.)
  ((equal diam 300. 0.001) 324.)))
(defun sel-dial ()
;;;(setq fname (vl-filename-mktemp "liso.dcl"))
(setq fname (strcat (getvar "dwgprefix") "pipe-len.dcl"))
(setq fn (open fname "w"))
(write-line
"sel_layer : dialog {" fn)
(write-line (strcat "label = " "\"" "SELECT LAYER TO GET LENGTH" "\"" ";") fn)
(write-line  "spacer_1;" fn)
(write-line  ":list_box {" fn)
(write-line (strcat "key = " "\""  "alist" "\"" ";") fn)
(write-line (strcat "label = " "\""  "Layer list" "\"" ";") fn)
(write-line "width=45;" fn)
(write-line "height=10;" fn)
(write-line "allow_accept=true;" fn)
(write-line "multiple_select=false;}" fn)
(write-line "spacer_0;" fn)
(write-line "spacer_0;" fn)
(write-line "ok_cancel;}" fn)
(close fn)
)
;=================main programm===================
(defun C:pi (/ acsp adoc all_layers axss choice
          ;|comp_data|; ;=> global
          dcl_id dia1 dia2 diam filt
          ;|fname|; ;=> global
          ll lyr
          mask pipe_len_list pt_list rad1 rad2
          sum_volume sv total_length tmp unit_volume ur)
(setvar "cmdecho" 0)
(setvar "expert" 2)
  (vl-load-com)
  (setq  adoc (vla-get-activedocument
         (vlax-get-acad-object)
       )
  )
  (if (and
  (= (getvar "tilemode") 0)
  (= (getvar "cvport") 1)
      )
    (setq acsp (vla-get-paperspace adoc))
    (setq acsp (vla-get-modelspace adoc))
  )
 (setq mask "DN");layer mask, i.e.: "DN 150 piping for vent from cyclone"
 (while
  (setq diam (getint "\nInner diameter [Enter to stop]: \n"))
(setq all_layers (get-layer-by-diam mask diam))
(sel-dial)
(setq dcl_id (load_dialog fname))
(new_dialog "sel_layer" dcl_id)
      (start_list "alist")
      (mapcar 'add_list all_layers)
      (end_list)
      (action_tile "alist" "(setq choice $value)")
      (start_dialog)
      (unload_dialog dcl_id)
      (done_dialog)
      (vl-file-delete fname)
(if choice
  (progn
  (setq lyr (nth (atoi choice) all_layers))
  (setq filt (filter-layer lyr))
  (ssget "_X" filt)
  (setq dia2 diam dia1 (get-ext-dia diam))
  (setq axss (vla-get-activeselectionset adoc))
  (if axss
    (progn
 (setq rad1 (/ dia1 2.)
       rad2 (/ dia2 2.)
      sv (* pi (- (expt rad1 2)(expt rad2 2))))
(setq unit_volume sv)
(setq sum_volume 0.)
(vlax-for a axss
  (setq tmp (vlax-get a 'Volume))
  (setq sum_volume (+  tmp sum_volume)))
  (setq total_length (/  sum_volume unit_volume 1000.))
  (setq pipe_len_list (strcat "Layer: " lyr "\n"
                  "Diameter: " (itoa diam) "\n"            
                  "Length: " (rtos total_length 2 5) " метров"))
  (setq comp_data (cons pipe_len_list comp_data))
  (alert (vl-princ-to-string pipe_len_list))
(vla-clear axss)
(vla-delete axss)
(vlax-release-object axss))
    (progn
      (alert "No pipes on this layer!")
      )
    )
    )
(alert "\nNo layers selected!")
)
  )
(setvar "cmdecho" 1)
(setvar "expert" 0)
(princ)
)
(prompt "\n")
(prompt "\t\t<<< Type pi to execute :  >>>  \n")
(princ)
;;;TesT : (C:pi)
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

> Олег(jr.)
Все работает, суппер!!!
Огромнейшое спасибо за помощь!!!
Один маленькй вопрос - нет ли у тебя желания дописать в программе проверочного условия, типа:
если на слое такого сечения трубы нет, то  не считать объем и соответственно не выдавать длину трубы, т.к. если обозвать любой слой типа "DN 65" и там нарисована стена, то он считает длинну труб?
В любом случае улучшать можно программу до безконечности, поєтому ее достаточно, для того чтобы кратно облегчить жизнь чертежникам..

Re: Как программно измерить длину труб в 3D-чертеже?

> Vitaliy
Боюсь, что на лиспе это сделать невозможно,
единственный путь, стандартизировать слои
(как наприм. в английский стандартах) и конечно
на слоях труб не рисовать ничего кроме.
По-крайней мере мне лично это не по зубам...
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

> Олег(jr.)
Это я так дабы не закрывать тему предложил...
Я начал работать в 3D только месяц и всякие проги для меня большое открытие, поэтому не понимая как это работает предлагаю всякую глупость..:)
Твоя программка сократила мое время для создания спецификации как минимум в 10 раз!!!!
Ты даже не представляешь как ты мне помог...
С уважением Vitaliy

Re: Как программно измерить длину труб в 3D-чертеже?

> Vitaliy
Рад помочь
Успехов
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

Ребята, извините темного (не проводить параллель с романом "Ночной дозор" :) ), но я не могу запустить этот лисп. Как это сделать? Вводил "all-layers-by-mask" - не прокатило. Не сильно разбираюсь в подобных командах.
Извините, если не в тему. ПОМОГИТЕ!

Re: Как программно измерить длину труб в 3D-чертеже?

pi с ком.строки надо вводить.

Re: Как программно измерить длину труб в 3D-чертеже?

> Denver 22
Там такая суть: каждая система, т.е. каждая
труба нарисована на отдельном слое
Каждый слой начинается с одинакового префикса:
наприм. в конкретном случае маска слоя (или префикс) - "DN".
Названия слоев выглядят так: "DN <и далее название системы>"
Потом ты немного путаешь all-layers-by-mask  это функция, значит она вызывается в скобках
(см. внутри тела основной программы), а C:pi -это
команда, и как всякая команда в командной строке
вызывается без скобок (не буду останавливаться на
исключениях типа C:cal и т.д.) т.е. вводи только выражение после С:
Будут вопросы, задавай
Успехов

> kpblc
Спасибо за поддержку :)
~'J'~

Re: Как программно измерить длину труб в 3D-чертеже?

Спасибо большое. Нашел почему набирать pi. Впреть буду внимательней.

Re: Как программно измерить длину труб в 3D-чертеже?

Чё то у меня фигню выдаёт!