Jump to content

Lisp to prompt user to select options then set layer and insert Block - Lisp Code Optimization


Recommended Posts

Posted

Hi I had a stab at my second lisp wrote from scratch. It works!... but I feel like I created a long winded way and open my self room for error with the layers need to be set 100 correct.

 

I would also like to improve the code so it can loop inserting the block or at least remember the last selections maybe?

 

Any advise on improving or optimizing or critising the lisp is welcomed. Thank you

 

;; Prompts the user to select through two round of options then based on the selection will set the appropriate layer and insert the block
(defun c:LE-Manhole ()
  ;initget sets the options for the user to select
  (initget 1 "Existing Proposed")
  ;MHCondition is the variable that stores the user's selection regarding the condition of the manhole
  (setq MHCondition
    (getkword
      "\nSelect an option [Existing/Proposed]: "
    )
  )
  ;The cond function checks the user's selection and sets the MHC variable accordingly 0 for Existing and 10 for Proposed
  (cond
    ((= MHCondition "Existing") (princ "\nYou selected Existing.") (setq MHC 0))
    ((= MHCondition "Proposed") (princ "\nYou selected Proposed.") (setq MHC 10))
    (t (princ "\nNo valid option selected."))
  )
  (princ)
  
  ;initget sets the options for the user to select the type of manhole
  ;MHS is the variable that stores the user's selection regarding the type of manhole
  (initget 1 "Adoptable Private Highways")
  (setq MHState
    (getkword
      "\nSelect an option [Adoptable/Private/Highways]: "
    )
  )
  ;The cond function checks the user's selection and sets the MHS variable accordingly 1 for Adoptable, 2 for Private, and 3 for Highways
  (cond
    ((= MHState "Adoptable") (princ "\nYou selected Adoptable.") (setq MHS 1))
    ((= MHState "Private") (princ "\nYou selected Private.") (setq MHS 2))
    ((= MHState "Highways") (princ "\nYou selected Highways.") (setq MHS 3))
    (t (princ "\nNo valid option selected."))
  )
  (princ)
  ;Status is the variable that stores the sum of MHC and MHS to determine the final selection
  ;Existing Public	  1
  ;Existing Private	  2
  ;Existing Highways	3
  ;Proposed Public	  11
  ;Proposed Private	  12
  ;Proposed Highways	13

  ;The cond function checks the value of Status and sets the current layer accordingly
  ;The setvar function sets the current layer to the specified layer based on the user's selection
  (setq Status (+ MHC MHS))
  (cond
    ((= Status 1) (princ "\nYou selected Existing Public.")   
     (setvar "clayer""-LE-D-SW-Existing Public Sewer"))
    
    ((= Status 2) (princ "\nYou selected Existing Private.")  
     (setvar "clayer""-LE-D-SW-Existing Drainage"))
    
    ((= Status 3) (princ "\nYou selected Existing Highways.") 
     (setvar "clayer""-LE-D-SW-Existing Highway Drainage"))
    
    ((= Status 11) (princ "\nYou selected Proposed Public.")  
     (setvar "clayer""-LE-D-SW-Adoptable Manhole"))
    
    ((= Status 12) (princ "\nYou selected Proposed Private.") 
     (setvar "clayer""-LE-D-SW-Private Manhole"))
    
    ((= Status 13) (princ "\nYou selected Proposed Highways.")
     (setvar "clayer""-LE-D-SW-Highway Manhole"))
    
    (t (princ "\nNo valid option selected."))
  )
  (princ)  
  
  ;Inserts Manhole Block
  (command "_.-INSERT" "Manhole" (getpoint "\nPick the insertion point for the block: ") "1" "" "")
  
)

 

Posted

Having to do lots of pits you missed one thing and that manholes often need rotating. Not all manholes are round. We had all sorts of sizes of manholes for street drainage. Are your manholes only 1 size ? Have a look at this also. Multi GETVALS.lsp

Pit.lsp

Posted

Hi @BIGAL currently for UK the manholes for new project we specify are circular (the majority). Manholes vary in size and the Manhole Block has a visibility state to cycle through the options (personaly against visibility state, it would have been mode efficient to set up manhole dynamically with geometric constraints https://youtu.be/-4avuPOjmQA?si=lOd7aryeQknXUPfu )

Posted

As part of insert a dynamic block I have a pop up dcl so choose the visibility states, as part of the insert lisp just saves the pick on little arrow and choose. I can post if you want it works with any dynamic block.

Posted

I would suggest checking if the layer exists and if not I create it first.

 

should populate the TAGS after the insert in case the tags are out of order (happens when users modify blocks) and  Instead use Lee Mac's utilities. https://www.lee-mac.com/attributefunctions.html to populate to ensure the correct tag get the corresponding values.

For Dynamics look here https://www.lee-mac.com/dynamicblockfunctions.html

 

Another tip would be calling the block with the ".dwg" extension "Manhole.dwg" instead of Manhole (Reason is if the block doesn't exist in the drawing AutoCAD will check inside all the  "Support file search paths")

And last reset what ever custom parameters you used in the lisp. (things like color, snap modes, current layer and so on.....)

;; Set Attribute Value  -  Lee Mac
;; Sets the value of the first attribute with the given tag found within the block, if present.
;; blk - [vla] VLA Block Reference Object
;; tag - [str] Attribute TagString
;; val - [str] Attribute Value
;; Returns: [str] Attribute value if successful, else nil.

(defun LM:vl-setattributevalue ( blk tag val )
    (setq tag (strcase tag))
    (vl-some
       '(lambda ( att )
            (if (= tag (strcase (vla-get-tagstring att)))
                (progn (vla-put-textstring att val) val)
            )
        )
        (vlax-invoke blk 'getattributes)
    )
)



;; Prompts the user to select through two round of options then based on the selection will set the appropriate layer and insert the block
(defun c:LE-Manhole ( / InitialLayer layerName bscale LastEnt blk Tag Value InitialLayer)
  (setq InitialLayer (getvar 'clayer))  
  
  (defun *error* (errmsg) 
    (if (not (wcmatch errmsg "Function cancelled, quit / exit abort, console break"))
    (princ (strcat "\nError: " errmsg)))
    (setvar 'CLayer InitialLayer) 
  )
  
  
  ;initget sets the options for the user to select
  (initget 1 "Existing Proposed")
  ;MHCondition is the variable that stores the user's selection regarding the condition of the manhole
  (setq MHCondition
    (getkword
      "\nSelect an option [Existing/Proposed]: "
    )
  )
  ;The cond function checks the user's selection and sets the MHC variable accordingly 0 for Existing and 10 for Proposed
  (cond
    ((= MHCondition "Existing") (princ "\nYou selected Existing.") (setq MHC 0))
    ((= MHCondition "Proposed") (princ "\nYou selected Proposed.") (setq MHC 10))
    (t (princ "\nNo valid option selected."))
  )
  (princ)
  
  ;initget sets the options for the user to select the type of manhole
  ;MHS is the variable that stores the user's selection regarding the type of manhole
  (initget 1 "Adoptable Private Highways")
  (setq MHState
    (getkword
      "\nSelect an option [Adoptable/Private/Highways]: "
    )
  )
  ;The cond function checks the user's selection and sets the MHS variable accordingly 1 for Adoptable, 2 for Private, and 3 for Highways
  (cond
    ((= MHState "Adoptable") (princ "\nYou selected Adoptable.") (setq MHS 1))
    ((= MHState "Private") (princ "\nYou selected Private.") (setq MHS 2))
    ((= MHState "Highways") (princ "\nYou selected Highways.") (setq MHS 3))
    (t (princ "\nNo valid option selected."))
  )
  (princ)
  ;Status is the variable that stores the sum of MHC and MHS to determine the final selection
  ;Existing Public	  1
  ;Existing Private	  2
  ;Existing Highways	3
  ;Proposed Public	  11
  ;Proposed Private	  12
  ;Proposed Highways	13

  ;The cond function checks the value of Status and sets the current layer accordingly
  ;The setvar function sets the current layer to the specified layer based on the user's selection
  (setq Status (+ MHC MHS))
  (setq layerName
    (cond
      ((= Status 1) (princ "\nYou selected Existing Public.")   
        "-LE-D-SW-Existing Public Sewer"       )
      ((= Status 2) (princ "\nYou selected Existing Private.")  
      "-LE-D-SW-Existing Drainage")
      ((= Status 3) (princ "\nYou selected Existing Highways.") 
      "-LE-D-SW-Existing Highway Drainage")
      ((= Status 11) (princ "\nYou selected Proposed Public.")  
      "-LE-D-SW-Adoptable Manhole")
      ((= Status 12) (princ "\nYou selected Proposed Private.") 
      "-LE-D-SW-Private Manhole")
      ((= Status 13) (princ "\nYou selected Proposed Highways.")
      "-LE-D-SW-Highway Manhole")
      (t nil)
    )
  )
  (if layerName
    (progn 
      (if (not (tblsearch "LAYER" layerName)) ;; Check if layer exists
        (command "_LAYER" "M" layerName "C" "1" "" "LType" "Continuous" "" "") ;; Create layer (Red)
      )
    
      (setq bscale 1 blockName "Manhole.dwg")
      (command "_.-INSERT" blockName "S" bscale (getpoint "\nPlace Manhole: ") "")
      
      (setq LastEnt (entlast))
      
      (setq blk (vlax-ename->vla-object LastEnt))
      (setq Tag "TAG1" Value "1.0")
      (LM:vl-setattributevalue  blk Tag Value) 
      (setq Tag "TAG2" Value "2nd Value")
      (LM:vl-setattributevalue  blk Tag Value) 
     )
  )
  (setvar 'CLayer InitialLayer)  ; reset layer back
  (princ)
)

 

Posted

As suggested I forgot about this , use a check layer. Can be called very simply.

 

 ((= MHState "Adoptable") (princ "\nYou selected Adoptable.")(chklayer "Adoptable pits" 1 "Dashed") (setq MHS 1)) checks for the layer name and color.

 

(defun chklay (lay col lt / )
(if (not (tblsearch "LAYER" lay))
(command "-layer" "m" lay "c" col lay "lt" lt lay "")
(setvar 'clayer lay)
)
(princ)
)

 

  • Like 1
Posted

So basically define a new function. Are the items in the brackets after chklay parameters passed to the function?

Posted

Correct  I would suggest putting commonly used functions like this in a Common.lisp with global access definitions so you can call from any lisp.

 

;Setup Variables
(setq pLayername "My Test Layer"
      pColor 1
      pLineType "Continious")

;Calling the function
(chklay pLayername pColor pLineType)

 

 

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...