I've never used LISP before and I'm using AI to try to create simple automations for autocad so I can speedup the proccess. Everything works fine to the point where I have a let expression which takes as an argument list of variables for initialization but the second variable is mistaken for a function and thus when I try to run the script in AutoCad I get the following error:
Command: CASING
Enter offset value: 18
Do you want the offset vertical lines to span from the bottom line to the top line of the rectangle? (Y/N): y
Do you want the offset horizontal lines to span from the left line to the right line of the rectangle? (Y/N): y
Getting selection set
Filtering rectangles
Adding entity: <Entity name: 2889a984ea0>
Vertices: ((39.7611 42.9035) (174.28 42.9035) (174.28 220.962) (39.7611 220.962))
In the if ; error: no function definition: BOTTOM-RIGHT
Here is my lisp script:
(defun c:casing (/ ss rectangles i ent entData coords all-vertices offset vertical-span horizontal-span)
;; Load Visual LISP extension functions
(vl-load-com)
;; Function to count vertices of a polyline
(defun get-vertex-count (ent)
(cond
((= (cdr (assoc 0 ent)) "LWPOLYLINE")
(length (vl-remove-if-not '(lambda (x) (= (car x) 10)) ent)))
((= (cdr (assoc 0 ent)) "POLYLINE")
(let ((count 0) (vertex (entnext ent)))
(while (and vertex (= (cdr (assoc 0 (entget vertex))) "VERTEX"))
(setq count (1+ count))
(setq vertex (entnext vertex)))
count))
(t 0)))
;; Function to sort vertices in a consistent order
(defun sort-vertices (vertices)
;; Sort vertices by y-coordinate, then by x-coordinate
(setq vertices (vl-sort vertices (function (lambda (a b)
(if (/= (cadr a) (cadr b))
(< (cadr a) (cadr b))
(< (car a) (car b)))))))
;; Ensure the order is bottom-left, bottom-right, top-right, top-left
(if (> (car (nth 1 vertices)) (car (nth 0 vertices)))
(setq vertices (list (nth 0 vertices) (nth 1 vertices) (nth 3 vertices) (nth 2 vertices)))
(setq vertices (list (nth 1 vertices) (nth 0 vertices) (nth 2 vertices) (nth 3 vertices))))
vertices)
;; Prompt for offset value
(setq offset (getreal "\nEnter offset value: "))
;; Prompt for vertical span
(setq vertical-span (getstring "\nDo you want the offset vertical lines to span from the bottom line to the top line of the rectangle? (Y/N): "))
;; Prompt for horizontal span
(setq horizontal-span (getstring "\nDo you want the offset horizontal lines to span from the left line to the right line of the rectangle? (Y/N): "))
;; Get pre-selected objects or prompt for selection
(princ "\nGetting selection set")
(setq ss (ssget "_I"))
(if (null ss)
(setq ss (ssget)))
(if (null ss)
(progn
(alert "No objects selected! Select rectangles before running the command.")
(exit)))
;; Filter rectangles
(princ "\nFiltering rectangles")
(setq rectangles '())
(setq all-vertices '())
(setq i 0)
(while (< i (sslength ss))
(setq ent (ssname ss i))
(setq entData (entget ent))
(if (and (= (cdr (assoc 0 entData)) "LWPOLYLINE")
(= (cdr (assoc 70 entData)) 1)
(= (get-vertex-count entData) 4))
(progn
(princ "\nAdding entity: ") (princ ent)
(setq rectangles (cons ent rectangles))
(setq coords (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) entData)))
(setq coords (sort-vertices coords))
(setq all-vertices (cons coords all-vertices))))
(setq i (1+ i)))
(if (null rectangles)
(progn
(alert "No rectangles selected!")
(exit)))
;; Create offset lines
(foreach vertices all-vertices
(princ "\nVertices: ") (princ vertices)
(if (= (length vertices) 4)
(progn
(princ "\nIn the if ")
(let ((bottom-left (nth 0 vertices))
(bottom-right (nth 1 vertices))
(top-right (nth 2 vertices))
(top-left (nth 3 vertices)))
(princ "\nAfter foreach")
(princ "\nBottom-left: ") (princ bottom-left)
(princ "\nBottom-right: ") (princ bottom-right)
(princ "\nTop-right: ") (princ top-right)
(princ "\nTop-left: ") (princ top-left)
;; Create offset vertical lines
(if (equal vertical-span "Y" t)
(progn
(princ "\nBefore first line")
(command "LINE" (list (+ (car bottom-left) offset) (cadr bottom-left)) (list (+ (car top-left) offset) (cadr top-left)) "")
(princ "\nBefore second line")
(command "LINE" (list (- (car bottom-right) offset) (cadr bottom-right)) (list (- (car top-right) offset) (cadr top-right)) ""))
(progn
(command "LINE" (list (+ (car bottom-left) offset) (cadr bottom-left)) (list (+ (car bottom-left) offset) (cadr top-left)) "")
(command "LINE" (list (- (car bottom-right) offset) (cadr bottom-right)) (list (- (car bottom-right) offset) (cadr top-right)) "")))
;; Create offset horizontal lines
(if (equal horizontal-span "Y" t)
(progn
(command "LINE" (list (car bottom-left) (+ (cadr bottom-left) offset)) (list (car bottom-right) (+ (cadr bottom-right) offset)) "")
(command "LINE" (list (car top-left) (- (cadr top-left) offset)) (list (car top-right) (- (cadr top-right) offset)) ""))
(progn
(command "LINE" (list (car bottom-left) (+ (cadr bottom-left) offset)) (list (car bottom-right) (+ (cadr bottom-left) offset)) "")
(command "LINE" (list (car top-left) (- (cadr top-left) offset)) (list (car top-right) (- (cadr top-left) offset)) "")))))
(princ "\nError: Vertices list does not contain exactly 4 elements.")))
;; Output the vertices coordinates
(princ "\nVertices coordinates of selected rectangles: ")
(foreach vertices all-vertices
(princ "\nRectangle vertices: ") (princ vertices))
(princ "\nDone processing")
(princ))
The issue appears to be at line 81: (bottom-right (nth 1 vertices))
I checked the syntax multiple times. I checkt parentheses but everything seems fine for me. Used 3 different AI's to find the issue with no luck. Everything else except this part works as expected and I can't seem to figure out why. I checked the flow algorithm flow and syntax. Even got acquainted with the syntax and learned a little bit about lisp and how it works.
AutoLISP doesn't use let
to bind local variables. Instead, you declare them after /
in the parameter list, and then assign them. So add those four variables to the parameter list of c:casing
, and then use
(setq bottom-left (nth 0 vertices)
bottom-right (nth 1 vertices)
top-right (nth 2 vertices)
top-left (nth 3 vertices))