Jump to content

Insert blocks at the vertices of the polyline and align to the segments


pyou

Recommended Posts

Hi

 

I have found this great lisp code and would like to ask if there is a possibility to modify it to Insert blocks at the vertices of the polyline and align to the segments? Currently its just inserting one block in the middle of the line which is aligned to the segment.

 

Thank you

 

(defun c:bam (/ blk cnt c_spc ent m_dst m_pt n_obj r_ang sca ss)
  ;; Check that we have the block to insert
  (if (tblobjname "block" (setq blk "spot"))
    (progn (setq c_spc (vlax-get-property
			 (vla-get-activedocument (vlax-get-acad-object))
			 (if (= 1 (getvar 'cvport))
			   'paperspace
			   'modelspace
			 )
		       )
		 sca   1.		; < - Block scale
	   )
	   (prompt "\nSelect ARC,LINE,*POLYLINE,SPLINE: ")
	   ;; Check for selection or (sslength nil) below will bomb
	   (if (setq ss (ssget '((0 . "ARC,LINE,*POLYLINE,SPLINE"))))
	     (repeat (setq cnt (sslength ss))
	       (setq ent   (ssname ss (setq cnt (1- cnt)))
		     m_dst (/ (vlax-curve-getdistatparam ent (vlax-curve-getendparam ent)) 2)
		     m_pt  (vlax-curve-getpointatdist ent m_dst)
		     r_ang (angle '(0. 0. 0.)
				  (vlax-curve-getfirstderiv ent (vlax-curve-getparamatpoint ent m_pt))
			   )
		     n_obj (vlax-invoke c_spc 'insertblock m_pt blk sca sca sca r_ang)
	       )
	     )
	   )
    )
    (alert (strcat "\n" blk " needs to exist in drawing!"))
  )
  (princ)
)(vl-load-com)

 

Edited by pyou
Link to comment
Share on other sites

Pretty sure has been answered many times before, Google insert blocks at vertices Autocad Lisp

Edited by BIGAL
Link to comment
Share on other sites

2 minutes ago, BIGAL said:

Pretty sure has been answered many times before, Google insert blocks at vertices Autocad Lisp

Unfortunately not that simple  Alan,  as it needs to be not only inserted, but aligned along segment.

Link to comment
Share on other sites

  • pyou changed the title to Insert blocks at the vertices of the polyline and align to the segments
15 minutes ago, mhupp said:

 

I did see this one as well, unfortunately my drawing units are set to ''clockwise'' ticked.  So its not aligning blocks along segments. Is there a way to modify code if drawing units angle ticked clockwise ? Also code do not work with 3d Polylines.

 

(defun c:inscrossalonglw ( / mid bln ss i lw data dat k mp c )

  (defun mid ( p1 p2 )
    (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) p1 p2)
  )

  (vl-cmdf "_.UNDO" "_BE")
  (setq bln "SPOT")
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (repeat (setq i (sslength ss))
      (setq lw (ssname ss (setq i (1- i))))
      (setq data (vl-remove-if-not '(lambda ( x ) (vl-position (car x) '(10 42))) (entget lw)))
      (if (= 1 (logand 1 (cdr (assoc 70 (entget lw)))))
        (setq data (append data (list (car data) (last data))))
      )
      (setq dat data data nil)
      (while dat
        (setq data (cons (list (car dat) (cadr dat)) data))
        (setq dat (cddr dat))
      )
      (setq data (reverse data) k -1)
      (foreach d data
        (setq k (1+ k))
        (if (< k (1- (length data)))
          (if (zerop (cdr (cadr d)))
            (vl-cmdf "_.-INSERT" bln "_non" (cdr (car d)) 1.0 1.0 (cvunit (angle (cdr (car d)) (cdr (car (nth (1+ k) data)))) "radian" "degree"))
            (progn
              (setq mp (inters (cdr (car d)) (polar (cdr (car d)) (- (angle (cdr (car d)) (cdr (car (nth (1+ k) data)))) (atan (cdr (cadr d)))) 1.0) (cdr (car (nth (1+ k) data))) (polar (cdr (car (nth (1+ k) data))) (+ (angle (cdr (car (nth (1+ k) data))) (cdr (car d))) pi (atan (cdr (cadr d)))) 1.0) nil))
              (setq c (inters (mid (cdr (car d)) mp) (polar (mid (cdr (car d)) mp) (+ (angle (cdr (car d)) mp) (* 0.5 pi)) 1.0) (mid mp (cdr (car (nth (1+ k) data)))) (polar (mid mp (cdr (car (nth (1+ k) data)))) (+ (angle mp (cdr (car (nth (1+ k) data)))) (* 0.5 pi)) 1.0) nil))
              (vl-cmdf "_.-INSERT" bln "_non" (cdr (car d)) 1.0 1.0 (cvunit ((if (minusp (cdr (cadr d))) - +) (angle c (cdr (car d))) (* 0.5 pi)) "radian" "degree"))
            )
          )
        )
      )
    )
  )
  (vl-cmdf "_.UNDO" "_E")
  (princ)
)

 

Edited by pyou
Link to comment
Share on other sites

Maybe a sample drawing of what your looking to do?

 

is it a 3d polyline that is 2d but set an an elevation, or a true 3d poly line that moves in x y and z plains? is the block you want to insert also 3D? it would have to be oriented in the right way facing 0 degree like this.

 

image.png.20d4822861e3aa540283f714277db182.png

 

 

if a true 3d poly you would have to calculate  two angles the xy and zy angles. the link I posted is only calculating the xy angle.

maybe @marko_ribar has something that handles 3d poly lines.

Link to comment
Share on other sites

20 hours ago, mhupp said:

Maybe a sample drawing of what your looking to do?

 

is it a 3d polyline that is 2d but set an an elevation, or a true 3d poly line that moves in x y and z plains? is the block you want to insert also 3D? it would have to be oriented in the right way facing 0 degree like this.

 

image.png.20d4822861e3aa540283f714277db182.png

 

 

if a true 3d poly you would have to calculate  two angles the xy and zy angles. the link I posted is only calculating the xy angle.

maybe @marko_ribar has something that handles 3d poly lines.

 

example what I would like to achieve.  Simple block +   , it works on Polylines if I turn off ''clockwise'' in the units, if ''clockwise'' ticked  its not aligning blocks correctly. Yah would be great if it could work on 3d polylines same as very first lisp code.

test.dwg

Edited by pyou
Link to comment
Share on other sites

I turn off ''clockwise'' in the units, use (setvar 'Angdir 1)  and reset it, though I very rarely have to use it, so without going through code why would you need to use it.

 

3D polys can cheat and use the XY co-ords only for angle but insert at 3D XYZ.

  • Thanks 1
Link to comment
Share on other sites

You can change variables so the lisp will work properly with setvar. briscad usually tells you what they are in the properties

image.png.e98f7d31ce643d486b7d6c768add6bea.png

 

(getvar 'angdir) when check outputs 1 meaning clockwise

unchecked and run again 0

 

so you want to set angdir to 1 before calculating the angles

 

(setvar 'angdir 1) ;before angle calculations
(setvar 'angdir 0) ;set right before you exit lisp to restore your defaults

 

Anyway this should work with 3d polylines using the vlax-curve funcitons

 

;;----------------------------------------------------------------------------;;
;; Function to place block on vertices of 2d and 3d polyines
;; Note: Angle directin is set to clockwise after running
;; https://www.cadtutor.net/forum/topic/81001-insert-blocks-at-the-vertices-of-the-polyline-and-align-to-the-segments/#comment-631547
(defun c:foo (/ blk mspace i p1 p2 ang sca ss)
  (vl-load-com)
  ;Check that we have the block to insert
  (if (tblobjname "block" (setq blk "spot"))
    (progn
      (setq mspace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (prompt "\nSelect POLYLINE: ")
      (setvar 'angdir 1)
      (if (setq ss (ssget '((0 . "*POLYLINE"))))
        (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
          (setq i 0)
          (while (< i (vlax-curve-getEndParam ent)) ;get the number of vertex in the polyline
            (setq p1 (vlax-curve-getPointAtParam ent i) ;get point at i
                  p2 (vlax-curve-getPointAtParam ent (1+ i)) ;get point at next vertex
                  ang (angle p1 p2)
            )
            (setq i (1+ i))
            (vlax-invoke mspace 'insertblock p1 blk 1 1 1 ang)
          )
        )
      )
    )
    (alert (strcat "\n" blk " needs to exist in drawing!"))
  )
  (setvar 'angdir 0)
  (princ)
)

 

  • Thanks 1
Link to comment
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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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...