CivilTechSource Posted May 21 Posted May 21 Hi, I am trying to write a lisp that will insert a block based on where the user will click. However, before the user clicks I want to give the user the option to select at which layer he wants that block to be placed on. So below is the code for the lisp to check if the layers exist. (if (not (tblsearch "LAYER" "INSERT LAYER NAME HERE")) (command "-LAYER" "_M" "INSERT LAYER NAME HERE" "_C" 1 "INSERT LAYER NAME HERE" "")) The next step is to use the -insert command to bring the block visual to the screen so the user can see the block prior to placing it. The challenge I want to fix is that when the -insert command is activated I want the getkword function to be available so the user can select/cycle through the layer that the block will be based on and I want the preview visual of the -insert command to reflect the layer selection the user selected. I might be overcomplicating it but I thought if I am going to do something might as well make it a nice user experience. So the question is: Is there a way during the -insert command to activate the getkword function and still be active until the user places the block and then onto the next block placement? Thanks in advance Quote
BIGAL Posted May 22 Posted May 22 If you make an insert lisp it would be easiest to change the layer prior to insert or even change it after insert. You could use a dcl list of layers that say match a certain group of layer names. You could have more than one insert lisp so multiple groups of layers. Even select an existing object and set to its layer. Eg Trees group "small tree" "medium tree" "gum tree" 1 1 Quote
mhupp Posted May 22 Posted May 22 5 hours ago, CivilTechSource said: Is there a way during the -insert command to activate the getkword function and still be active until the user places the block and then onto the next block placement? lisp isn't multi thread so you either have to store things and call them later in the lisp or do things in a logical order like BIGAL points out. see if this works save current layer (Modified) ListSelect to select what layer you want to insert on change current layer to picked "pauses" insert command for user to select point change back to old layer InsertBlock.lsp 1 Quote
CivilTechSource Posted May 22 Author Posted May 22 That makes sense BIGAL, the challenge I am facing is that the -insert command when used to bring blocks outside of the drawing (with support file path set up) it brings the whole drawing as a block. Currently I have the below macro on a button: *^C^C-insert;"LE-D-Manhole";\;;;explode;last;-purge;Blocks;"LE-D-Manhole";N; So basically I have a separate dwg called LE-D-Manhole with a Manhole block in their. And when I use the insert command it brings the content of the LE-D-Manhole as one block and then I explode it. But that means that the block inside the LE-D-Manhole does not get to be placed on the layer that was set during the -insert command. Quote
Steven P Posted May 22 Posted May 22 To do what you want ideally might be possible but you are going to have to spend some time to make it so. Perhaps that investment in time will be worth it, perhaps not. You might first off look at Lee Macs 'Steal' routine - allows you to pick a block in another drawing to import (I think), then use something like (entlast) and (entmod.....) to change the imported blocks layer. As Mhupp says make the process a logical order for you - select layer before or after insert. And so onto a whole world of programming... If you look at grread, grdraw and grvecs, help says "Only specialized AutoLISP routines need this function." Grread will return what the user is doing, whether it is a mouse movement, mouse click, keyboard entry. - If keyboard entry you can record this as the layer to insert into, create the layer as you go. - If mouse click you can use this as user wants to place block there and then run the insert command according to the pointer location at the mouse click - and now the fun part, if mouse movement is recorded Look at grdraw and grvecs, Lee Mac has some examples on his website, you can draw temporary lines on the screen, these can be redrawn every time the mouse is moved using the output of grread as the mouse position. You can get the 'bylayer' colour of the blocks destination layer and graw these lines a suitable colour if you want. You are also going to want to create a vector list for an approximation of the new blocks shape (vector list: list of points to draw lines between) - approximation because grvecs only draws lines, not curves or text. You might be happy to represent the block as a rectangle using bounding box method to get the size. Final thing is to find the zoom level of the space you are drawing into (else any lines you draw will always be the same regardless of zoom on or out) So now with a vector list of approximate points for the block, the layer colour, and scale you can draw with grvecs lines on the screen to show the block at the right colour and scaled to the space zoom level. This can follow the mouse pointer. Putting all this together anytime the mouse moves after block selection the block representation will be shown on screen, until mouse click text can be entered to change the layer. And I reckon this would take a while to make it nice - a week or more for me. I'd use steal.... 1 Quote
CivilTechSource Posted May 22 Author Posted May 22 Hi Mhupp, thanks for taking the time providing the list. I run it and throws and error at line 11. (setvar "CLAYER" layname) Quote
CivilTechSource Posted May 22 Author Posted May 22 I did try to use the command "clayer" layname and still did not work. Quote
GLAVCVS Posted May 22 Posted May 22 Is it possible that that layer does not exist or is locked? Quote
mhupp Posted May 22 Posted May 22 Change it to 'clayer. Check against how I'm setting olay Been out of the lisp programming for a bit. @GLAVCVS The popup should only shows existing layers in drawing. But doesn't check lock state. As for expolding block and then they are on diff layers. Search the fourm for Lastent loop have that right before the explode then use the selection set to move this to the picked layer. Quote
CivilTechSource Posted May 22 Author Posted May 22 Thanks everyone for their input. The below code is what I managed to get working. I want to improve this by making the command repeatable in terms of placing the block or clicking something to change the previous selections. is this possible? ;;Takes the user through a two step selection process and then inserts the block on the defined layer based on the two steps. (defun c:LE-ManholeFW () ;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") (setq MHState (getkword "\nSelect an option [Adoptable/Private]: " ) ) ;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)) (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-FW-Existing Public Manhole")) ((= Status 2) (princ "\nYou selected Existing Private.") (setvar "clayer""-LE-D-FW-Existing Manhole")) ((= Status 11) (princ "\nYou selected Proposed Public.") (setvar "clayer""-LE-D-FW-Adoptable Manhole")) ((= Status 12) (princ "\nYou selected Proposed Private.") (setvar "clayer""-LE-D-FW-Private Manhole")) (t (princ "\nNo valid option selected.")) ) (princ) ;Inserts Manhole Block (command "_.-INSERT" "Manhole" (getpoint "\nPick the insertion point for the block: ") "1" "" "") ) 1 Quote
BIGAL Posted May 23 Posted May 23 Add a checklayer defun before setting the current layer. This includes color and linetype. (defun chklay (lay col lt / ) (if(not(tblsearch "LAYER" lay)) (command "-layer" "m" lay "c" col lay "lt" lt lay "") (princ "exist") ) (setvar 'clayer lay) ) For me I use a dcl for questions. If you want it ask. 1 Quote
Recommended Posts
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.