Place a block at start and end of every line on layer

Place a block at start and end of every line on layer

jacob.dillingham.engr
Participant Participant
345 Views
3 Replies
Message 1 of 4

Place a block at start and end of every line on layer

jacob.dillingham.engr
Participant
Participant

I have a layer that only contains pathing for an automated vehicle. I then need to place a "QR CODE" block at every start and end point of all the lines of that pathing. The placed block needs to be on a different layer. I got ChatGPT to start the code I'm just having a hard time getting it working and am not a very competent programmer. Any suggestions or help guys?

(defun c:QRPlace ()
(setq line_layer "MUSA-AGV-AMR PATH")
(setq qr_block_name "QR CODE")
(setq qr_block_layer "MUSA-QR CODES")
(setq tolerance 0.05) ; 5% tolerance for coordinate check

(if (and (tblsearch "LAYER" line_layer) (tblsearch "BLOCK" qr_block_name) (tblsearch "LAYER" qr_block_layer))
(progn
(setq points '()) ; Initialize list to store points
(setq ss (ssget "_X" (list '(0 . "LINE") '(8 . line_layer)))) ; Select lines on specified layer
(if ss
(progn
(setq i 0)
(while (< i (sslength ss))
(setq ent (ssname ss i))
(setq startpt (cdr (assoc 10 (entget ent)))) ; Get the start point of the line
(setq endpt (cdr (assoc 11 (entget ent)))) ; Get the end point of the line

; Check for duplicates or close coordinates and add to the list
(if (and (not (member startpt points :test 'equalp))
(not (member endpt points :test 'equalp))
(not (is-close-coord startpt points tolerance))
(not (is-close-coord endpt points tolerance)))
(progn
(setq points (cons startpt points))
(setq points (cons endpt points))
)
)
(setq i (1+ i))
)

; Insert QR CODE block at unique points in the list
(foreach point points
(command "_insert" qr_block_name point) ; Insert block at the point
(command "_.chprop" "_last" "" "LA" qr_block_layer "") ; Change block to QR CODES layer
)
(princ "\nQR CODE blocks inserted successfully at unique points of lines on specified layer.")
)
(princ "\nNo lines found on the specified layer.")
)
)
(princ "\nLayer or block not found. Please check the names.")
)
)

(defun is-close-coord (coord lst tol)
; Check if the coordinate is close to any coordinate in the list within the given tolerance
(foreach item lst
(if (and (<= (distance coord item) tol) (>= (distance coord item) (- tol)))
(return T)
)
)
nil
)

0 Likes
346 Views
3 Replies
Replies (3)
Message 2 of 4

Kent1Cooper
Consultant
Consultant

ChatGPT is notoriously bad at a lot of AutoLisp things -- it really just doesn't know enough about how it works yet.  Some things I notice right off the bat:

 

(setq ss (ssget "_X" (list '(0 . "LINE") '(8 . line_layer)))) ; Select lines on specified layer

 

You can't use a variable name in that way, inside a "quoted list" where things that need evaluation are not allowed.  It would need to be:

 

(setq ss (ssget "_X" (list '(0 . "LINE") (cons 8 line_layer)))) ; Select lines on specified layer

 

(if (and (not (member startpt points :test 'equalp))
(not (member endpt points :test 'equalp))

 

Those have too many arguments for a (member) function, and the :test 'equalp parts must be coming from some other programming language or something.

 

(if (and (<= (distance coord item) tol) (>= (distance coord item) (- tol)))
(return T)

 

The (distance) function always returns a positive number, so the (and) there and the second (distance) function it contains are wrong.

And there's no (return) function -- probably also something ChatGPT is assuming based on some other programming language.

Kent Cooper, AIA
0 Likes
Message 3 of 4

paullimapa
Mentor
Mentor

I would also change this section of the code:

 

; Insert QR CODE block at unique points in the list
(foreach point points
(command "_insert" qr_block_name point) ; Insert block at the point
(command "_.chprop" "_last" "" "LA" qr_block_layer "") ; Change block to QR CODES layer
)

 

You can avoid the chprop command by setting that layer current before inserting the block like this (of course this all assume you have a layer "MUSA-QR CODES"):

 

(setq clayer (getvar 'clayer)) ; save current layer setting
(setvar 'clayer qr_block_layer) ; set the desired layer current 
; then run foreach loop
(foreach....
) 
; after foreach loop
(setvar 'clayer clayer) ; restore layer back to original setting

 

You can also learn the sequence of the insert command by entering the following at the command prompt:

 

Command: -INSERT
Enter block name or [?] <QR CODE>: QR CODE
Units: Unitless   Conversion: 1.0000000000E+00
Specify insertion point or [Basepoint/Scale/X/Y/Z/Rotate]: 0,0
Enter X scale factor, specify opposite corner, or [Corner/XYZ] <1>: 1
Enter Y scale factor <use X scale factor>: 1
Specify rotation angle <0>: 0

 

The lisp code equivalent would then be:

 

(command "_.Insert" qr_block_name point 1 1 0) ; Insert block at the point

 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 4 of 4

Sea-Haven
Mentor
Mentor

Just a suggestion, Google "block at every start and end point of all the lines Autocad lisp" what your asking for has been solved before.

0 Likes