Jump to content

Inserting Dynamic Blocks along the points of Polyline using LISP


Recommended Posts

sanetmunde

Hi, I want a LISP routine which can insert blocks along the polyline.

I have two dynamic blocks. They are 'Straight Duct' and 'Elbow90'. Consider I draw a polyline with three XY coordinates i.e. (1,1) , (1,2) and (2,2) and insert rectangular block with desired 'Width'. Here are list of things I want from LISP program:

1. I want 'Straight Duct' to be inserted at mid-points of '(1,1) & (1,2)' and '(1,2) & (2,2)'.

2. Also, those inserted blocks should be rotated with an angle made by those points with horizontal so that 'Straight Duct' remains along the line. Example, Angle made by line joining points '(1,1) & (1,2)' with horizontal is 90 Deg. Hence, Dynamic Block should be rotated by 90 degree about midpoint.

3. Move the grip of 'Straight Duct' (which facing to open end of polyline) to the open end of polyline. Move other grip of 'Straight Duct' to the length of (150+ Width/2) mm less than the intersection point.

4. Insert 'Elbow90' at the point with polar angle 45 Degree to point of intersection and polar radius (150 + Width/2) mm. Also, the grip of elbow should be moved so that width of 'Elbow90' should be as same as that of 'Straight Duct'.

Pls refer the attached file for understanding the problem.

Can anyone help me out?

HVAC Dynamic Blocks 24.04.2018.dwg

Link to post
Share on other sites
hanhphuc
Hi, I want a LISP routine which can insert blocks along the polyline....

1. I want 'Straight Duct' to be inserted at mid-points of '(1,1) & (1,2)' and '(1,2) & (2,2)'...

...

Can anyone help me out?

 

we prefer this volunteering forum is more for discussion than asking for freebies. if you learned then you can solve it yourself in future :)

 

 


(defun c:dbtest (/ s doc spc en w r obj pt blk )
;hanhphuc 25.04.2018
 
 (if (and
(tblsearch "Block" "[b][color="purple"]Straight Duct[/color][/b]")
      		 (setq 	doc '(( l / doc) (setq doc (vlax-get-acad-object)) (foreach x l (setq doc (vlax-get doc x))))
       	 	spc  (doc '(ActiveDocument ActiveLayout Block))
             		)
	(while (not s)
	(setq s (ssget "_:S:L+." '((0 . "LWPOLYLINE")(-4 . "=" )(70 . 0))))
                 )
         	(setq en (ssname s 0))
[color="green"];;; (setq en (car (entsel "\nPlease select LWPOLYLINE.. ")))
;;;  (eq (cdr (assoc 0 (entget en))) "LWPOLYLINE")[/color]
          (progn (initget 7)
                 (setq  w (getdist "\nWidth of the duct : ")
                       r (+ (/ w 2.0) 150.)
                       )
                 (setvar 'filletrad r)
                 (vl-cmdf "_FILLET" "P" en) 
                 )
          (setq obj (vlax-invoke (vlax-ename->vla-object en) 'explode))
          )
   (progn 
     	    (foreach x (mapcar ''((a) (mapcar ''((x) (vlax-get a x)) '(StartPoint EndPoint)))
                           (vl-remove-if ''((x) (/= "AcDbLine" (vla-get-ObjectName x))) obj)
                              )
            
            (setq pt  (apply 'mapcar (cons ''((a b)(* 0.5 (+ a b))) x))
                  blk (vla-InsertBlock spc (vlax-3d-point pt) "[color="purple"][b]Straight Duct[/b][/color]" 1 1 1 (apply 'angle x) )
                  )
            ([color="blue"][b]LM:SETDYNPROPVALUE[/b][/color] blk "[b][color="purple"]Legnth[/color][/b]" (apply 'distance x))
            ([color="blue"][b]LM:SETDYNPROPVALUE[/b][/color] blk "[b][color="purple"]Width[/color][/b]" w)
            (vlax-put blk 'InsertionPoint pt)
            )
     
          (foreach x (mapcar ''((a) (vlax-get a 'Center))
                            (vl-remove-if ''((x) (/= "AcDbArc" (vla-get-ObjectName x))) obj)
                             )

            [color="green"] ;This is example to draw circle [/color]
            (entmakex (list '(0 . "CIRCLE") (cons 10 x) (cons 40 [color=red][b]150[/b][/color] )))

[color="green"]             ;Try Coding yourself here ... refer to the above example
     ;Insert block "[b]ELBOW90[/b]"
	     ;You need to identify which quadrant or rotation to suit 
     ;or let other volunteers to guide you :-)
[/color]
	
            )

          )
   (progn
   (alert "\nOops.. please retry! ")
   (command "start" "explorer \"http://www.cadtutor.net/forum/showthread.php?104092-Inserting-Dynamic-Blocks-along-the-points-of-Polyline-using-LISP\"")
   )

   )
 (princ)
 )


[color="green"];; Get Dynamic Block Property Value  -  Lee Mac
;; Returns the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)[/color]
(defun LM:getdynpropvalue ( blk prp )
   (setq prp (strcase prp))
   (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value)))
       (vlax-invoke blk 'getdynamicblockproperties)
   )
)

[color="green"];; Set Dynamic Block Property Value  -  Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil[/color]
(defun LM:setdynpropvalue ( blk prp val )
   (setq prp (strcase prp))
   (vl-some
      '(lambda ( x )
           (if (= prp (strcase (vla-get-propertyname x)))
               (progn
                   (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
                   (cond (val) (t))
               )
           )
       )
       (vlax-invoke blk 'getdynamicblockproperties)
   )
)

(vl-load-com)

Edited by hanhphuc
'mid,ssget,add link,comments,radius=150
Link to post
Share on other sites

hanhphuc well done but a simpler answer may have been search for "DUCT" I know that a couple of the stars here have some good packages and your right they may not be free.

Link to post
Share on other sites
sanetmunde

Thank you for the Response. I have learned some basics and modified a program which can insert blocks along the polyline with required rotation and at required point. Here is the code.

 

 

(defun C:PtoDB (/ plent plobj coords num pt p1 p2 p3 ang1 ang2 diff width ang3 p4)
 (setq
   plent (car (entsel "\nSelect Polyline: "))
   plobj (vlax-ename->vla-object plent)
   coords (vlax-get plobj 'Coordinates); un-differentiated list of X Y [& Z if applicable] coordinate values
 ); setq
 (setq num (if (= (cdr (assoc 0 (entget plent))) "LWPOLYLINE") 2 3))
   ; LW Polylines have only X & Y; "heavy" 2D & 3D have X Y & Z
 (repeat (/ (length coords) num)
   (repeat num ; number of coordinates to separate into a point list
     (setq
       pt (append pt (list (car coords)))
       coords (cdr coords)
     )
   ); repeat
 ); repeat
 (setq pt (reverse pt)); list of coordinates divided up into point lists
 (setq width (getint "Enter the width of duct:"))
  
 (setq p1 (list (nth 1 pt) (nth 0 pt) 0))
 (setq p2 (list (nth 3 pt) (nth 2 pt) 0))
 (setq p3 (list (nth 5 pt) (nth 4 pt) 0))
 (setq ang1 (angtos (angle p1 p2)))  
 (setq ang2 (angtos (angle p2 p3)))
 (setq diff (+ 150 (/ width 2)))
 
 (cond ((and (or (> (cadr p2) (cadr p1)) (> (cadr p2) (cadr p3))) (or (> (car p2) (car p1)) (> (car p2) (car p3))))
(setq ang3 (itoa 0))
(setq p4 (list (- (car p2) diff) (- (cadr p2) diff) 0))
)
  ((and (or (> (cadr p2) (cadr p1)) (> (cadr p2) (cadr p3))) (or (< (car p2) (car p1)) (< (car p2) (car p3))))
(setq ang3 (itoa 90))
(setq p4 (list (+ (car p2) diff) (- (cadr p2) diff) 0))
)
((and (or (< (cadr p2) (cadr p1)) (< (cadr p2) (cadr p3))) (or (< (car p2) (car p1)) (< (car p2) (car p3))))
(setq ang3 (itoa 180))
(setq p4 (list (+ (car p2) diff) (+ (cadr p2) diff) 0))
)
((and (or (< (cadr p2) (cadr p1)) (< (cadr p2) (cadr p3))) (or (> (car p2) (car p1)) (> (car p2) (car p3))))
(setq ang3 (itoa 270))
(setq p4 (list (- (car p2) diff) (+ (cadr p2) diff) 0))
)
 )
 ;(print ang3)
 ;(foreach n p4 (print n))
 (command "_Insert" "Straight Duct" "_mtp" p1 p2 1 "" ang1)
 (command "_Insert" "Straight Duct" "_mtp" p2 p3 1 "" ang2)
 (command "_Insert" "Elbow90" p4 1 "" ang3)
); defun

 

 

Now, I am working on stretching the grips of dynamic block using LISP. I need to get grips adjusted as per variable "Width". Can you refer some similar thread?

Link to post
Share on other sites
hanhphuc
hanhphuc well done but a simpler answer may have been search for "DUCT" I know that a couple of the stars here have some good packages and your right they may not be free.

should thanks to handy functions by Lee :thumbsup: save half of coding times!

 

i'm not the HVAC guy, so i can't comment correct or wrong.

 

p/s: as an outsider: explode - double offset filleted lwpolyline does the trick :)

but there must be some reason why using dynamic blocks?

Link to post
Share on other sites
hanhphuc
Thank you for the Response. I have learned some basics and modified a program which can insert blocks along the polyline with required rotation and at required point. Here is the code.

(defun C:PtoDB ...)

Now, I am working on stretching the grips of dynamic block using LISP. I need to get grips adjusted as per variable "Width". Can you refer some similar thread?

 

Good try. AFAIK autolisp can't make it. It can be done by modifying vla-GetDynamicBlockProperties via VLisp. look at the sub-function by Lee Mac above.

for "Straight Duct" - Legnth & Width

for "elbow90" - Width1 & Width2

 

Note: But my version does not support some grips in new version, so you need to try your own

 

GMmqmF0.gif

 

p/s : legnth length ,typos?

Link to post
Share on other sites
sanetmunde

I already have a program which convert points into polylines with required 'Width'. I want to use Dynamic Block for Data Extraction. VLISP looks difficult to understand. I will try to modify sub-function by Lee Mac and will let you know.

Thank you

Link to post
Share on other sites
hanhphuc
I already have a program which convert points into polylines with required 'Width'. I want to use Dynamic Block for Data Extraction. VLISP looks difficult to understand. I will try to modify sub-function by Lee Mac and will let you know.

Thank you

 

i don't think VLISP is difficult as you think, put some time to study you'll find it's magic!

example you can calculate mid point block( insertion point ) along polyline with

vlax-curve- functions

vlax-curve-getdistat.. vlax-curve-getpointat.. vlax-curve-getEndpointat.. etc.. you just need to supply the argument then it works like magic without complex math calculation!!

 

you don't need to modify Lee's function, it works by just supplying required arguments.

Lee wrote some others useful dynamic block functions, just look at his website

Edited by hanhphuc
link added
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...