Trouble with setting up an autolisp to work with an AutoCAD array function

Trouble with setting up an autolisp to work with an AutoCAD array function

jhall6Z3NG
Participant Participant
272 Views
5 Replies
Message 1 of 6

Trouble with setting up an autolisp to work with an AutoCAD array function

jhall6Z3NG
Participant
Participant

Some people have seen portions of this Autolisp before. I solved one problem and encounter more as I progressed into the abyss of confusion. So here it goes! Some people have asked for me to post the whole Autolisp routine so suggestions can be made help improve what I am trying to accomplish. the specific problem I am having now is with the Array Command. I have had success with the command and it has performed without a hitch. I have since tweaked to routine and now it does not function as it is suppose to. So far the function works all the way through to the  array and I get and error  "invalid option keyword." (see screenshot). I changed the the array function to a suggestion given by a google search (how to get Autocad array function to work with lisp" the result kicked out by AI is where the command presently sits. I have tried several iteration of the array with mixed results (-array, _.array, _array, _arraypolar, etc). I was trying to find my last posting to find out if it was working then, but was unable to find it.

 
(command "-array" "l" "" "_p" "0,0" BH_qty "" "n") ; does not execute the command in the autolisp routine though it works when type directly into Autocad? The PNG can attest to the success of the command. If I can get the command (-array) to work when typed direcly into Autocad why does it not work with Autolisp in the same manor? This is why the confusion is racking my brain? The logic conflicts? Again, I appreciate any suggestions to help improve my commands.
 
I set this up to make the initial object at 0,0, but I would like to make this work at a selected point in the future. I welcome inputs in that regard as well. I also have some confusion about the local and global variables. My previous thoughts might be wrong in that line of thinking? I was under the impression the local variables (first row parenthesis) stays within the Baseringcmd function, once it's closed the variable reference drops?

 

(defun c:baseringcmd (/ OD ID BC HalfBC pt1 BHD thk)
 
  (setq OD (getdist "\nSpecify base ring OD:"))
    (command "_.circle" "0,0" "d" OD)
    (setq Osdia (entlast)) 
  
  (setq ID (getdist "\nSpecify base ring ID:"))
    (command "_.circle" "0,0" "d" ID)
    (setq ISdia (entlast))
 
   (setq BC (getdist "\nSpecify bolt circle diameter:"))
  (if BC
    (progn
      (setq halfBC (/ BC 2.0))
      (princ (strcat "\nHalf the BC distance is: " (rtos halfBC)))
      )
    )
 
  (setq pt1 (list 0.0 halfBC))
  (setq BHD (getdist "\nSpecify bolt hole diameter:")) 
    (command "_.circle" pt1 "d" BHD)
  
   (command "-view" "_swiso")
 
   (setq BH_qty (getint "\nSpecify the number of bolt holes:")) ; Autodesk "Sea Haven" suggestion 
    (setq BHQ_Array (entlast))    
        
  (command "rotate" "l" "" "0,0" (/(/ 360 BH_qty) 2)) 
 
  (if (= (tblsearch "layer" "Plate") nil)
    (command "layer" "m" "Plate" "c" 204 "" "")
  )
  (command "chprop" OSdia "" "la" "Plate" "")
  (command "layer" "s" "0")
 
  (setq BH_array (ssget BHQ_array)
    (if BH_array
      (progn
(command "_array" BH_array "" "_p" "0,0" BH_qty "" "n")
      )
    (princ "\nNo objects selected.")
    ) ; end if
  ;(princ)
    
; recomendation from Autodesk "Kent1Cooper"
;(command "_.array" "_last" "" "_polar" boltcenter "_items" nbolt "")
;"BH_qty" for nbolt, does not type in Autocad
 
  (setq thk1 (getdist "\nSpecify base ring thickness:"))
    (command "_.extrude" OSdia ISdia BHQ_array "" thk1)
 
  (Command "subtract" OSdia "" ISdia "") ; BHQ_Array "")
 
;  (princ)
😉
0 Likes
Accepted solutions (1)
273 Views
5 Replies
Replies (5)
Message 2 of 6

Sea-Haven
Mentor
Mentor
Accepted solution

This is my attempt, I removed some of the error checking if you dont answer then the code will fail anyway, so you should have for the Dia's a default value if you press Enter.

 

(defun c:baseringcmd (/ OD ID BC HalfBC pt1 BHD thk oldsnap)
 
 (setq oldsnap (getvar 'osmode))
 (setvar 'osmode 0)
 
 (setq pt (getpoint "\nPick centre point of flange "))
 
 (if (= (tblsearch "layer" "Plate") nil)
    (command "layer" "m" "Plate" "c" 204 "" "")
 )
 
 (setvar 'clayer "Plate")
 (setq OD (getdist "\nSpecify base ring OD:"))
 (command "_.circle" pt "d" OD)
 (setvar 'clayer "0")
  
 (setq ID (getdist "\nSpecify base ring ID:"))
 (command "_.circle" pt "d" ID)
 
 (setq BC (getdist "\nSpecify bolt circle diameter:"))
 ; (if BC
  ;  (progn
  (setq halfBC (/ BC 2.0))
    (princ (strcat "\nHalf the BC distance is: " (rtos halfBC)))
  ;    )
 ; )
 (setq p2 (mapcar '+ pt (list 0.0 halfBC 0.0)))
 ; (setq pt1 (list 0.0 halfBC))
  (setq BHD (getdist "\nSpecify bolt hole diameter:")) 
  (command "_.circle" p2 "d" BHD)
  (setq BH_array (entlast))
  
  ; (command "-view" "_swiso")

   (setq BH_qty (getint "\nSpecify the number of bolt holes:")) ; Autodesk "Sea Haven" suggestion 
        
 ;  (command "rotate" "l" "" "0,0" (/(/ 360 BH_qty) 2)) 
 
   ; (if BH_array
    ;  (progn
   (command "_array" BH_array "" "_p" pt BH_qty 360 "n")
 ;     )
 ;   (princ "\nNo objects selected.")
  ;  ) ; end if
  
  (setvar 'osmode oldsnap)
  (princ)
    
)
(C:BASERINGCMD)

 Version 2 has a dcl input and you can set default values.

 

(defun c:baseringcmd (/ OD ID BC HalfBC pt1 BHD thk oldsnap)
 
 (setq oldsnap (getvar 'osmode))
 (setvar 'osmode 0)
 
 (setq pt (getpoint "\nPick centre point of flange "))
 
 (if (= (tblsearch "layer" "Plate") nil)
    (command "layer" "m" "Plate" "c" 204 "" "")
 )
 
 (setvar 'clayer "Plate")
 
 (if (not AH:getvalsm)(load "Multi Getvals.lsp"))
 (setq ans (AH:getvalsm (list "Enter values " "OD" 5 4 "200" "ID" 5 4 "100" "Bolt hole dia" 5 4 "150" "Bolt size" 5 4 "12" "Number of bolts" 5 4 "6")))
 (setq OD (atof (nth 0 ans))
 ID (atof (nth 1 ans))
 BC (atof (nth 2 ans))
 BHD (atof (nth 3 ans))
 BH_qty (atof (nth 4 ans))
 )

 (command "_.circle" pt "d" OD)
 (setvar 'clayer "0")
  
 (command "_.circle" pt "d" ID)

 (setq halfBC (/ BC 2.0))
 (princ (strcat "\nHalf the BC distance is: " (rtos halfBC)))

 (setq p2 (mapcar '+ pt (list 0.0 halfBC 0.0)))

 (command "_.circle" p2 "d" BHD)
 (setq BH_array (entlast))

 (command "_array" BH_array "" "_p" pt BH_qty 360 "n")
  
  (setvar 'osmode oldsnap)
  (princ)
    
)
(C:BASERINGCMD)

 

SeaHaven_1-1755132070764.png

 

Message 3 of 6

jhall6Z3NG
Participant
Participant

Thank you for taking the time to help. Forgive me and my ignorance, but I a couple of questions. I see some advantages from your first option. I have to ask, for clarification about something you suggested. You set "pt" up from the beginning and that will allow me to pick any point on the screen to place the plate, what is the purpose of setting "p2" with "mapcar". could you explain what the expression was asking for and the variables you used? I also should explain further what my overall goal was here when the baseringcmd was finished. What I am looking for by the end of this exercise is a 3D solid plate with the inside hole and the bolt holes subtracted from the outer solid. I was never able to clear the hurdle of the array, to get to the rest of the function, to see if they would work. The hardest thing I was running into and not exactly understanding is getting  previously set variable to recall later in the process. This is going to be subsequently be part of a much larger entity. I personally have worked with Autocad for more than 30 years and though I may know the commands and shortcut I use to draw, understanding LISPs? I am as green as they get. I see numerous advantages to this and realized I should have looked into these routines sooner. It would have sped up allot of my drawing. So thanks again for helping a novice.

0 Likes
Message 4 of 6

Sea-Haven
Mentor
Mentor

If you want a 3d solid as the answer, then you just need to look at how solids are made, I am sure others will comment, solids are not my field of expertise. 

 

The mapcar function just adds a val1 val2 val3  values to a point XYZ, yes could use (Polar pt ang dist) or (setq p2 (list (+ (car pt) dist) (cadr pt)))

 

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/trouble-with-setting-up-an-autolisp-to-work-with-an-autocad/m-p/13767794#M165883
: Make flange by AlanH August 2025

(defun c:baseringcmd (/ OD ID BC HalfBC pt1 BHD thk oldsnap)
 
(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)
 
(setq pt (getpoint "\nPick centre point of flange "))
 
(if (= (tblsearch "layer" "Plate") nil)
    (command "layer" "m" "Plate" "c" 204 "" "")
)
 
(setvar 'clayer "Plate")
 
(if (not AH:getvalsm)(load "Multi Getvals.lsp"))
(setq ans (AH:getvalsm (list "Enter values " "OD" 5 4 "200" "ID" 5 4 "100" "Thickness " 5 4 "12" "Bolt hole dia" 5 4 "150" "Bolt size" 5 4 "12" "Number of bolts" 5 4 "6")))
(setq OD (atof (nth 0 ans))
  ID (atof (nth 1 ans))
  Th (atof (nth 2 ans))
  BC (atof (nth 3 ans))
  BHD (atof (nth 4 ans))
  BH_qty (atoi (nth 5 ans))
)

(command "_.circle" pt "d" OD)
(command "extrude" (entlast) "" th)
(setq ODSOL (entlast))

(command "_.circle" pt "d" ID)
(command "extrude" (entlast) "" th)
(command "subtract" ODSOL "" (entlast) "")
(setq odsol (entlast))

(setq halfBC (/ BC 2.0))
(princ (strcat "\nHalf the BC distance is: " (rtos halfBC)))
(setq ang 0.0 angdiff (/ (* 2 pi) bh_qty))
(setq p2 (polar pt ang halfBC))

(repeat BH_qty
  (command "_.circle" p2 "d" BHD)
  (command "extrude" (entlast) "" th)
  (command "subtract" ODSOL "" (entlast) "")
  (setq odsol (entlast))
  (setq p2 (polar pt (setq ang (+ ang angdiff)) halfBC))
)
(command "vpoint" "-1,-1,1")
(command "hide")
(setvar 'osmode oldsnap)
(princ)

)
(C:BASERINGCMD)

 

0 Likes
Message 5 of 6

komondormrex
Mentor
Mentor

@jhall6Z3NG

yet another one, spiced with activex

(defun c:baseringcmd (/ OD Osdia ID ISdia BC halfBC pt1 BHD BH_qty BHQ_Array 
            hole space holes_list thk to_extrude_list reg_list extruded_list extruded_sset
           )
  (setq OD (getdist "\nSpecify base ring OD:"))
    (command "_.circle" "0,0" "d" OD)
    (setq Osdia (entlast))
    (setq ID (getdist "\nSpecify base ring ID:"))
    (command "_.circle" "0,0" "d" ID)
    (setq ISdia (entlast))
    (setq BC (getdist "\nSpecify bolt circle diameter:"))
    (if BC
        (progn
          (setq halfBC (/ BC 2.0))
          (princ (strcat "\nHalf the BC distance is: " (rtos halfBC)))
        )
    )
    (setq pt1 (list 0.0 halfBC))
    (setq BHD (getdist "\nSpecify bolt hole diameter:"))
    (command "_.circle" pt1 "d" BHD)
     (command "-view" "_swiso")
     (setq BH_qty (getint "\nSpecify the number of bolt holes:")) ; Autodesk "Sea Haven" suggestion
    (setq BHQ_Array (entlast))
  (setq hole (vlax-ename->vla-object BHQ_array)) 
    (command "rotate" "l" "" "0,0" (/ (/ 360. BH_qty) 2))
  (if BHQ_Array
    (setq holes_list (cons hole (vlax-safearray->list (vlax-variant-value (vla-arraypolar hole BH_qty (* 2 pi) (vlax-3d-point 0 0 0))))))
      (princ "\nNo objects selected.")
    )

    (setq thk (getdist "\nSpecify base ring thickness:"))
  (setq space (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object)))))
  (setq to_extrude_list (append holes_list (list (vlax-ename->vla-object ISdia) (vlax-ename->vla-object OSdia))))  
  (setq reg_list (mapcar '(lambda (object) (car (vlax-safearray->list 
                          (vlax-variant-value 
                            (vla-addregion space 
                                     (vlax-safearray-fill 
                                       (vlax-make-safearray vlax-vbobject '(0 . 0)) (list object)
                                     )
                            )
                          )
                           )
                       )
              )
                 to_extrude_list
           )
  )
  (setq extruded_list (mapcar '(lambda (object) (vla-addextrudedsolid space object thk 0))
                 reg_list
               )
  )
  (vla-update (vlax-get-acad-object)) 
  (mapcar 'vla-erase (append to_extrude_list reg_list))
  (setq extruded_sset (ssadd))
    (command "subtract" (vlax-vla-object->ename (last extruded_list)) "" 
            (foreach object (vl-remove (last extruded_list) extruded_list) 
                 (setq extruded_sset (ssadd (vlax-vla-object->ename object) extruded_sset))
            ) ""
  )
  (entmod (append (entget (entlast)) '((8 . "Plate") (62 . 204))))
    (princ)
)
0 Likes
Message 6 of 6

jhall6Z3NG
Participant
Participant

Thank you for all the inputs. There is obviously more than one way to skin a "function". I finally have a working product with Presspull as the final command in the function. with combinations of some of Sea Haven's suggestions and commands I needed to remain intact to see and view the final product. Thanks again for helping me get past my "Array".  Not exactly sure what cased the glitch in the execution of that command, but were are working as advertised. Except for completely auto finishing the Presspull command. I try three separate suggestions to know avail. The commands I had after Presspull were forced to go in front of it. I still get the finished product I was looking for, so thanks again for all the help.

I provided the "Function" below in case it helps someone else down the road, or further suggestions to improve upon later.

 

defun c:baseringcmd (/ OD ID BC HalfBC pt1 BHD pt2 BH_qty BHQ_array oldsnap)

  (setq oldsnap (getvar 'osmode))
  (setvar 'osmode 0)
 
  (setq pt1 (getpoint "\npick center point of flange: "))
 
  (if (= (tblsearch "layer" "Plate") nil)
    (command "layer" "m" "Plate" "c" "120" "" "")
  )

  (setq OD (getdist "\nSpecify base ring OD:"))
    (command "_.circle" pt1 "d" OD)

  (setq ID (getdist "\nSpecify base ring ID:"))
    (command "_.circle" pt1 "d" ID)

    (setq BC (getdist "\nSpecify bolt circle diameter:"))
     (setq halfBC (/ BC 2.0))
     (princ (strcat "\nHalf the BC distance is: " (rtos halfBC)))

  (setq pt2 (mapcar '+ pt1 (list 0.0 halfBC 0.0)))
  (setq BHD (getdist "\nSpecify bolt hole diameter:"))
    (command "_.circle" pt2 "d" BHD)

  (command "-view" "_swiso")

  (setq BH_qty (getint "\nSpecify the number of bolt holes:"))
    (setq BHQ_Array (entlast))
       
  (command "rotate" "l" "" pt1 (/(/ 360 BH_qty) 2)) ; rotates bolt holes to straddle C/L
 
  (command "_array" BHQ_array "" "p" pt1 BH_qty "" "n")
   
  (setvar 'osmode oldsnap)

  (command "_vscurrent" "_c" "")
 
  (command "._PRESSPULL"
 
  (princ)
)
0 Likes