CivilTechSource Posted April 19 Posted April 19 Is it possible to write a lisp code that will create a polyline based on user input and once complete it places a block (user input on position)? I a civil engineer and was wondering if I can create a command eg. Draw Retaining wall, and then the lisp will select the layer then initiate the PL command and once done it will automatically ask the user where to place the Retaining Wall heigh block. Thanks in advance for any guidance. Quote
Steven P Posted April 19 Posted April 19 Yes, that is possible, might need a few more details though. Second thing to ask, what are your LISP abilities like, do you want to create the solution if we give you hints and help along the way or will you need more guidance? 1 Quote
CivilTechSource Posted April 19 Author Posted April 19 Hi Steven, Thanks for getting back to me. I am actively trying to learn so my abilities/knowledge fall in the noob/beginner region. I think the tricky part is how do we ask the lisp to check if the polyline is complete? Because if the user hits ESC after drawing few vertex, does it still class as complete? If you can be kind to give hints and guidance. Thank you (defun c:draw_polyline_and_insert_block () ;Search if Layer exists. If not create one (if (not (tblsearch "LAYER" "Retaining Wall")) (command "-LAYER" "_M" "Retaining Wall" "_C" 1 "Retaining Wall" "")) (setvar "CLAYER" layer_name) ; Set the current layer ; Prompt user to draw a polyline (command "PLINE") ; Check if a polyline was actually created ; Define the block insertion point (setq ins_point (getpoint "Enter block insertion point: ")) ; Define the block name. Assumes the block exists (setq block_name "RW Text") ; Insert the block ;Is there a way to preview the block during insertion and rotation? (command "_insert" "Retaining Text" ins_point 1 1 0 "") ) Quote
BIGAL Posted April 20 Posted April 20 (edited) The obvious is avoid an ESC use a Enter or a close. Re location, once you draw a pline you can enter a length and work out a point at that length on a pline. (setq pt (vlax-curve-getpointatdist obj dist)) The second thing you can get for that point is the angle of the pline at that point so can rotate block if needed. Edited April 20 by BIGAL Quote
fuccaro Posted April 20 Posted April 20 Just a small hint: If you create the polyline vith entmake, just put something like (cons 8 "RetainingWall"). It will put the polyline on the desired layer if that layer exists and it will create it if it doesen't. Also I vould use a shorter name for the program name. 1 Quote
GLAVCVS Posted April 20 Posted April 20 (edited) Based on the answers given so far, it's possible I haven't fully understood your question. But I'll answer it anyway. If you want to interactively view the block to be inserted during the insertion process, you should first check if the command offers that option during execution: type '(command "_insert" "RetainingWall")' on the command line and add parameters to see if the command's behavior suits your needs. If not, then you can resort to a safer solution: the "move" command. The idea is to first insert the block at point 0,0 and call "(command "_move" (entlast) '(0 0))" And... voilà: you'll have the block visible at your cursor, waiting for you to tell it where to place it. Edited April 20 by GLAVCVS 1 Quote
Steven P Posted April 20 Posted April 20 Easter Sunday, CAD is off but extracting, copy and paste with no testing I think this is kind of what you are looking to add into a code: Things like escape will escape the full LISP where as finishing entity like polyline with enter will let it continues as it should. Can add in details to create the block at a specific layer - add the 'cons 8' example fuccaro above, but first see if this works. Technique is to create the block, then the entities and then finish the block (setq MyBlockName "Retaining_Wall") ;;Block Name, change as required (setq origin (list 0 0 0)) ;;Block origin,alter as required (entmake (list '(0 . "BLOCK") (cons 2 MyBlockName) (cons 70 64) (cons 10 origin) )) ;;Start block definition ;;Create the block entities here: (command "PLINE") ;;..... ;;Finish block entities. (entmakex '((0 . "ENDBLK"))) ;;Finish Block definition (setq NewBlock (tblobjname "BLOCK" MyBlockName)) ; entity description of new block. Think could also use (entlast) ? (command "-insert" NewBlock pause "" 1 pause) ;; Insert block, scale 1. 'NewBlock' might be MyBlockName ? 1 Quote
Steven P Posted April 22 Posted April 22 Update to above: Looking at this with CAD running this morning. For my code above you need to 'entmake' the block entities within the block definition part rather than draw them - possible to do but you don't get the graphical view on the screen what you are doing. Switched it around to select the entities first, copy them within the block definition then delete the originals once the block is created. Insert the block using entmake method - a bit neater I think to make a block on a set layer - rather than altering the drawing layer settings and back or inserting a block and then switching the layer after. You can add any entities you like to the block or adjust the (ssget) part to filter as required. I've put the 'fixed' details like block name as separate variables - it is possible to have user inputs here for some versatility. (defun c:test ( / MySS acount MyBlockName Origin MyLayer) (setq MySS (ssget)) ;;Select entities to convert to a block (setq MyBlockName "Retaining_Wall") ;;Block Name, change as required. Could use uaser input for block name (setq Origin (getpoint "Select Block Origin")) ;;Block origin,alter as required. Could hard code this to say (0 0 0) (setq MyLayer "RetainingWall") ;;Layer Name. Could use user input for layer name (setq LayerColour 1) ;;Layer Colour. (if (not (tblsearch "LAYER" MyLayer)) (command "-LAYER" "_M" MyLayer "_C" LayerColour MyLayer "")) ;; Create layer if necessary (setq NewBlock (entmakex (list (cons 0 "BLOCK") (cons 2 MyBlockName) (cons 70 64) (cons 10 Origin) )) ) ;;Start block definition (setq acount 0) ;; A counter (while (< acount (sslength MySS)) ;; make entities withn block (entmake (entget (ssname MySS acount))) ;; Remake entity within block (setq acount (+ acount 1)) ) ; end while (setq EndBlock (entmakex '((0 . "ENDBLK"))) ) ;;Finish Block definition (command "erase" MySS "") ;;Delete original objects, comment out if not required (entmakex (list (cons 0 "INSERT") (cons 67 0) (cons 100 "AcDbEntity") ;; insert the block (cons 8 MyLayer) ;;Use layer here, no need to set current layer settings in drawing (cons 100 "AcDbBlockReference") (cons 2 MyBlockName) (cons 10 Origin) (cons 41 1.0) (cons 42 1.0) (cons 43 1.0) (cons 50 0.0) (cons 70 0) (cons 71 0) (cons 44 0.0) (cons 45 0.0) )) (command "regen") ;; Regen Drawing (princ) ) 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.