I am interested in a lisp that will insert pipe diameter. The pipe is just a line or polyline. Blocks are placed on the pipe at different distances. The pipe dia will be placed in between two blocks with a dia symbol according to the following rule –
The number of block Dia
<=2 1”
2< No. of blocks <=3 1.25”
3< No. of blocks <=5 1.5”
5< No. of blocks <=10 2”
For better understand please see the attached file. Thanks in advance.
(vl-load-com)
(defun C:PipeDia (/ *error* _SortPtListByDist oCMDECHO oOSMODE doc ss ensel en i pt1 pt2 ptm pts pt1dist pt2dist txt)
;------
(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg)))
(setvar 'CMDECHO oCMDECHO)
(setvar 'OSMODE oOSMODE)
(vla-endundomark doc)
(princ))
;------
(defun _SortPtListByDist (ptList en)
;; Argument: Point list
;; Returns: Point list, sorted by distance from curve
;; By BlackBox
;; http://www.cadtutor.net/forum/showthread.php?61433-Help-Sort-a-list-point-by-distance
(mapcar
'(lambda (x / ptList2)
(setq ptList2 (append (cdr x) ptList2)))
(vl-sort
(mapcar
'(lambda (x / pt ptlist2)
(setq ptlist2
(append
(cons
(vlax-curve-getDistAtPoint
(ssname sspl 0)
(vlax-curve-getClosestPointTo en x T))
x)
ptlist2)))
ptList)
'(lambda (x y)
(< (car x) (car y))))))
;------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------
(vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
(setq oCMDECHO (getvar 'CMDECHO)
oOSMODE (getvar 'OSMODE))
(setvar 'CMDECHO 0)
(setvar 'OSMODE 0)
(if (and (princ "\nNeed BLOCKs, ")
(setq ss (ssget '((0 . "INSERT"))))
(< 2 (setq i (sslength ss)))
(setq ensel (entsel "\nSelect a (poly)line closer to beginning: "))
(wcmatch (cdr (assoc 0 (entget (setq en (car ensel))))) "LWPOLYLINE,LINE")
(if (> (vlax-curve-getDistAtPoint en (vlax-curve-getClosestPointTo en (cadr ensel) T))
(/ (vlax-curve-getDistAtParam en (vlax-curve-getEndParam en)) 2))
(progn
(command "_.REVERSE" en "")
(princ "\nPolyline was reversed."))
T)
(while (not (minusp (setq i (1- i))))
(setq pts (cons (vlax-curve-getClosestPointTo en (cdr (assoc 10 (entget (ssname ss i)))) T) pts)))
(setq pts (_SortPtListByDist pts en))
(setq i 0))
(repeat (1- (length pts))
(setq pt1 (nth i pts)
pt1dist (vlax-curve-getDistAtPoint en pt1)
pt2 (nth (1+ i) pts)
pt2dist (vlax-curve-getDistAtPoint en pt2)
ptm (vlax-curve-getPointAtDist en (+ pt1dist (/ (- pt2dist pt1dist) 2))))
(cond ((< i 2) (setq txt "%%c1\""))
((< i 3) (setq txt "%%c1.25\""))
((< i 5) (setq txt "%%c1.5\""))
((< i 10) (setq txt "%%c2\""))
(T (setq txt "%%c")))
(command "_.TEXT" ptm "1\'3\"" "" txt)
(setq i (1+ i)))
(princ "\nWrong selection, need BLOCKs."))
(setvar 'OSMODE oOSMODE)
(setvar 'CMDECHO oCMDECHO)
(vla-endundomark doc)
(princ)
)
If the error persist, post the dwg and try find what line is causing that.
Use VLIDE command in autocad, in editor open youre pipedia.lsp. Then in Menu Debug / mark Break on Error. Then load pipedia with Ctrl+Alt+E. Then activate Autocad with Window/Activate Autocad and then run command PIPEDIA. If you get an error, find a line with Ctrl+F9 in Editor.
Great! worked like a magic. Loving the community! It will save a lot of time, thank you so much. I am wondering if it is possible to do the same thing for the entire piping system (I am new, so I didn't post it first as I don't know whether it is possible) with the following rule -
The number of block Dia
<=2 1”
2< No. of blocks <=3 1.25”
3< No. of blocks <=5 1.5”
5< No. of blocks <=10 2”
5< No. of blocks <=10 2”
10< No. of blocks <=20 2.25”
20< No. of blocks <=40 3”
40< No. of blocks <=100 4”
100< No. of blocks <=275 6”
and also dimensioning it. I appolize that it may be an inappropriate question. Again Thank you very much..
(vl-load-com)
(defun C:PipeDia (/ *error* _SortPtListByDist oCMDECHO oOSMODE doc ss ensel en i pt1 pt2 ptm pts pt1dist pt2dist txt)
;------
(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg)))
(setvar 'CMDECHO oCMDECHO)
(setvar 'OSMODE oOSMODE)
(vla-endundomark doc)
(princ))
;------
(defun _SortPtListByDist (ptList en)
;; Argument: Point list
;; Returns: Point list, sorted by distance from curve
;; By BlackBox
;; http://www.cadtutor.net/forum/showthread.php?61433-Help-Sort-a-list-point-by-distance
(mapcar
'(lambda (x / ptList2)
(setq ptList2 (append (cdr x) ptList2)))
(vl-sort
(mapcar
'(lambda (x / pt ptlist2)
(setq ptlist2
(append
(cons
(vlax-curve-getDistAtPoint
en
(vlax-curve-getClosestPointTo en x T))
x)
ptlist2)))
ptList)
'(lambda (x y)
(< (car x) (car y))))))
;------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------
(vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
(setq oCMDECHO (getvar 'CMDECHO)
oOSMODE (getvar 'OSMODE))
(setvar 'CMDECHO 0)
(setvar 'OSMODE 0)
(if (and (princ "\nNeed BLOCKs, ")
(setq ss (ssget '((0 . "INSERT"))))
(< 2 (setq i (sslength ss)))
(setq ensel (entsel "\nSelect a (poly)line closer to beginning: "))
(wcmatch (cdr (assoc 0 (entget (setq en (car ensel))))) "LWPOLYLINE,LINE")
(if (> (vlax-curve-getDistAtPoint en (vlax-curve-getClosestPointTo en (cadr ensel) T))
(/ (vlax-curve-getDistAtParam en (vlax-curve-getEndParam en)) 2))
(progn
(command "_.REVERSE" en "")
(princ "\nPolyline was reversed."))
T)
(while (not (minusp (setq i (1- i))))
(setq pts (cons (vlax-curve-getClosestPointTo en (cdr (assoc 10 (entget (ssname ss i)))) T) pts)))
(setq pts (_SortPtListByDist pts en))
(setq i 0))
(repeat (1- (length pts))
(setq pt1 (nth i pts)
pt1dist (vlax-curve-getDistAtPoint en pt1)
pt2 (nth (1+ i) pts)
pt2dist (vlax-curve-getDistAtPoint en pt2)
ptm (vlax-curve-getPointAtDist en (+ pt1dist (/ (- pt2dist pt1dist) 2))))
(cond ((< i 2) (setq txt "%%c1\""))
((< i 3) (setq txt "%%c1.25\""))
((< i 5) (setq txt "%%c1.5\""))
((< i 10) (setq txt "%%c2\""))
((< i 20) (setq txt "%%c2.25\""))
((< i 40) (setq txt "%%c3\""))
((< i 100) (setq txt "%%c4\""))
((< i 275) (setq txt "%%c6\""))
(T (setq txt "%%c")))
(command "_.TEXT" ptm "1\'3\"" "" txt)
(setq i (1+ i)))
(princ "\nWrong selection, need BLOCKs."))
(setvar 'OSMODE oOSMODE)
(setvar 'CMDECHO oCMDECHO)
(vla-endundomark doc)
(princ)
)
Dimensioning I'll do next time. But it would be quite similar... I tried find some "block dimensioning" on web and I'm surprised I couldn't find some...
... I am wondering if it is possible to do the same thing for the entire piping system ...
Yes, it can. Well, almost, with some restrictions and requirements - look at the attachment, adjusted dwg:
- Each tube has its single line or polyline in the right direction (your previous drawing contained one line for opposite tubes with opposite flow - is not possible). For a multiple break you can use one of the CABs routines - very nice.
- Blocks are assigned the its curve based on distances (less than 10 inches). Blocks must be inserted with sufficient accuracy. - The cross main pipe can not be labeled - you can include this (poly)line in a selection, but it has no blocks closer than 10 inches, would not labeled) - Selection function is properly filtered - when selecting a window can be applied to the entire system objects, other than blocks, lines and polylines will be excluded) - When selected, you can check the direction of the curves (marked with points at beginnings), you cat manually select the one with wrong direction a reverse it.
- You cad try what can be done and what not - but it is not bulletproof 🙂
This task is for a separate routine. So make a new thread on this topic. This principle of making dims between blocks can be generally used... Maybe someone comes up with nice and simple solution. If not, i'll make it later.
- The cross main pipe can not be labeled - you can include this (poly)line in a selection, but it has no blocks closer than 10 inches, would not labeled)
I figured this out on my way to work... It would be a separated routine... calculation would use thelatesttexts (dia labels)of each tube. So I need the formula to calculate diameters of main tube.
- The cross main pipe can not be labeled - you can include this (poly)line in a selection, but it has no blocks closer than 10 inches, would not labeled)
I figured this out on my way to work...
I addeed this feature as well. And made some corrections....
- you can select your main pipe as well (as part of main selection).
- if only one polyline left (all others has blocks close or on..) - this one will be recognize as main pipe automatically. It there is none or more then one, you will be asked for selection
- in first part of routine where you can check and reverse direction... I made a little change - If is the line long enought (>50) is the mark point made at distance of 20, in other cases (< 50) is made in its beginning point (some lines has length of 0)