brianhiroshi Posted February 11, 2009 Share Posted February 11, 2009 Hi there! I'm new at AutoCAD and AutoLisp and I was trying to transform a set of lines that I've created in Autolisp into a single block. Is it possible? If someone knows how to do it, please give me a hand. Thanks Quote Link to comment Share on other sites More sharing options...
fixo Posted February 11, 2009 Share Posted February 11, 2009 Here is my old one I don't remeber how it's working Give this a try (defun C:AXB (/ acsp adoc block_coll block_def bname bpt cnt hgt i obj_list ob_list opt promp pt ss tag val ) (vl-load-com) (setq adoc (vla-get-activedocument (vlax-get-acad-object) ) ) (if (and (= (getvar "tilemode") 0) (= (getvar "cvport") 1) ) (setq acsp (vla-get-paperspace adoc)) (setq acsp (vla-get-modelspace adoc)) ) (setq block_coll (vla-get-blocks adoc)) (vla-endundomark adoc ) (vla-startundomark adoc ) (prompt "\nSelect entities to add into block\n") (setq ss (ssget)) (setq i -1) (repeat (sslength ss) (setq obj_list (cons (vlax-ename->vla-object (ssname ss (setq i (1+ i))) ) obj_list ) ) ) (setq ob_list (reverse obj_list)) (initget 1) (setq bpt (getpoint "\nBase point Point >> ") bname (getstring T "\nEnter block label (block name) : \n") ) (setq block_def (vla-add block_coll (vlax-3D-Point bpt) bname)) (initget "Yes No") (setq opt (getkword "\nDo you want to add attribute(s) in this block? (Yes/No) <Y>\n")) (if (not opt) (setq opt "Yes") ) (if (eq opt "Yes") (progn (setq hgt (getreal "\nEnter text height <0.05>: \n")) (if (not hgt) (setq hgt 0.05) ) (setq cnt 1) (while (setq pt (getpoint (strcat "\nPick " (itoa cnt) " attribute insertion point (Enter to stop) \n" ) ) ) (setq promp (strcase (getstring (strcat "\nEnter " (itoa cnt) " attribute prompt : \n" ) ) ) tag (strcase (getstring (strcat "\nEnter " (itoa cnt) " attribute tag : \n") ) ) val (getstring T (strcat "\nEnter " (itoa cnt) " attribute value : \n") ) pt (mapcar '- pt bpt) ) (vlax-invoke block_def 'Addattribute hgt acAttributeModeVerify promp pt tag val ) (setq cnt (1+ cnt)) ) (vla-copyobjects adoc (vlax-safearray-fill (vlax-make-safearray vlax-vbobject (cons 0 (1- (length obj_list))) ) obj_list ) block_def ) (vlax-release-object block_def) ) ) (vla-endundomark adoc ) (princ) ) (prompt "\n===========================\n") (prompt "\n Type AXB to run ... ") (prompt "\n===========================\n") (princ) ~'J'~ Quote Link to comment Share on other sites More sharing options...
brianhiroshi Posted February 11, 2009 Author Share Posted February 11, 2009 I've seen that with this lisp it is necessary for the user to select the lines. What I meant is that I've created an Autolip program do draws a hole (I've used many "._line" commands) and at the enn of the program I wanted that those lines were joined into a single block without having to select them. Do you think that's possible? Thanks!!! Quote Link to comment Share on other sites More sharing options...
fixo Posted February 11, 2009 Share Posted February 11, 2009 Forgot to say - welcome on board Try edited version instead (defun C:XB (/ acsp adoc block_coll block_def bname bpt cnt hgt i obj_list ob_list opt p1 p2 promp pt ss tag val ) (vl-load-com) (setq adoc (vla-get-activedocument (vlax-get-acad-object) ) ) (if (and (= (getvar "tilemode") 0) (= (getvar "cvport") 1) ) (setq acsp (vla-get-paperspace adoc)) (setq acsp (vla-get-modelspace adoc)) ) (setq block_coll (vla-get-blocks adoc)) (vla-endundomark adoc ) (vla-startundomark adoc ) (prompt "\nDraw the lines to add into block\n") (setq ss (ssadd)) (while (setq p1 (getpoint "\nSpecify starting point (or press Enter to Exit):")) (setq p2 (getpoint p1 "\nSpecify ending point: ")) (command "._line" "_non" p1 "_non" p2 "") (ssadd (entlast) ss)) (setq i -1) (repeat (sslength ss) (setq obj_list (cons (vlax-ename->vla-object (ssname ss (setq i (1+ i))) ) obj_list ) ) ) (setq ob_list (reverse obj_list)) (initget 1) (setq bpt (getpoint "\nBase point Point >> ")) (while (not (and (setq bname (getstring T "\nEnter block label (block name) : ")) (not (tblsearch "block" bname))) ) (princ "\nBlock already exist. Use another name") ) (setq block_def (vla-add block_coll (vlax-3D-Point bpt) bname)) (initget "Yes No") (setq opt (getkword "\nDo you want to add attribute(s) in this block? (Yes/No) <Y> : ")) (if (not opt) (setq opt "Yes") ) (if (eq opt "Yes") (progn (setq hgt (getreal "\nEnter text height <0.05>: ")) (if (not hgt) (setq hgt 0.05) ) (setq cnt 1) (while (setq pt (getpoint (strcat "\nPick " (itoa cnt) " attribute insertion point (Enter to stop) " ) ) ) (setq promp (strcase (getstring (strcat "\nEnter " (itoa cnt) " attribute prompt : " ) ) ) tag (strcase (getstring (strcat "\nEnter " (itoa cnt) " attribute tag : ") ) ) val (getstring T (strcat "\nEnter " (itoa cnt) " attribute value : ") ) pt (mapcar '- pt bpt) ) (vlax-invoke block_def 'Addattribute hgt acAttributeModeVerify promp pt tag val ) (setq cnt (1+ cnt)) ) ) ) (vla-copyobjects adoc (vlax-safearray-fill (vlax-make-safearray vlax-vbobject (cons 0 (1- (length obj_list))) ) obj_list ) block_def ) (vlax-release-object block_def) (initget "Yes No") (setq opt (getkword "\nDo you want to delete parent lines? (Yes/No) <Y> : ")) (if (not opt) (setq opt "Yes") ) (if (eq opt "Yes") (command "._erase" ss "") ) (vla-endundomark adoc ) (princ) ) (prompt "\n===========================\n") (prompt "\n Type XB to run ... ") (prompt "\n===========================\n") (princ) ~'J'~ Quote Link to comment Share on other sites More sharing options...
JohnM Posted February 12, 2009 Share Posted February 12, 2009 Creating a block in lisp can be difficult but you can take a short cut. If I understand correctly you could try this: At the beginning of your code make a blank selection set (setq ss1 (ssadd)) ;_makes a blank selection set Now right after your program creates 1 new object put this code (ssadd (entlast ss1)));_adds the last entity made to the selection set Example: (Command “_line” pt1 pt2 “”) (ssadd (entlast ss1)) (command “_Rectangle” pt1 pt2 ) (ssadd (entlast ss1)) If everything is done correctly you end up with a selection set with all the objects your program made. At the end of the program use this code. (command "-block" "block name" Ipt "p" "" "");_makes a block , the P = previous selection set made (command "-insert" "block name" Ipt "" "" "");_inserts the block Ipt = a point. Either use a point from your program or use the getpoint function to get a point. The reason there is a insert command is when you use the command line version of the block command there is no option to keep the block visible when made so it disappears. So we use the insert command to put it back and make it visible again. The problem will be the block name. You have to give it a name. If you are only going to use this once in a drawing then you can hard code the name. But if you want to use it more than once you have to give it a different name. There are 2 ways to do this. 1- If your picky about the block name then you will have to use the getstring function prior to the making of the block and pass the variable to it where it says, “block name”. 2- If you don’t care then you can use the date function to create a unique name every time the program is used and the pass it to the block command. Example: (setq blkname (strcat "BLK_"(itoa(fix(* 86400.0 (- (getvar "date") (fix (getvar "date"))))))));-unique name for block (command "-block" blkname Ipt "p" "" "");_makes a block (command "-insert" blkname Ipt "" "" "");_inserts the block Hope this helps. Making a block the other way is way more difficult and you still have the name issue. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 12, 2009 Share Posted February 12, 2009 A program I worked on with David Bethel ~ may be of some use here: (defun c:obj2blk1 (/ ss bn pt i ent elist) ; Get Entities (while (not ss) (princ "\nSelect Objects to Convert to Blocks:") (setq ss (ssget '((-4 . "<NOT") (0 . "INSERT,POLYLINE,VIEWPORT") (-4 . "NOT>")))) ) ;_ end while ; Get Block Name and Base Point (while (or (not bn) (not (snvalid bn)) ) ;_ end or (setq bn (getstring "Specify Block Name: ")) ) ;_ end while (initget 1) (setq pt (getpoint "Specify Base Point for Block: ")) ;;; Create BLOCK Header (entmake (list (cons 0 "BLOCK") (cons 10 pt) (cons 2 bn) (cons 70 0))) ;;;STEP THRU THE SET (setq i (sslength ss)) (while (>= i (setq i (1- i)) 0) (setq ent (ssname ss i) elist (entget ent) ) ;_ end setq (entmake elist) ) ;_ end while ;;;FINISH THE BLOCK DEFINITION (entmake (list (cons 0 "ENDBLK") (cons 8 "0"))) ;;;Insert the Block & Delete Originals (entmake (list (cons 0 "INSERT") (cons 2 bn) (cons 8 "0") (cons 10 pt))) (command "_.ERASE" ss "") (redraw) (prin1) ) ;_ end defun Quote Link to comment Share on other sites More sharing options...
brianhiroshi Posted February 12, 2009 Author Share Posted February 12, 2009 Thanks for the welcoming. I'm sorry to ask, but what does the "vla" do? There are some lisps that use it, but when I was reading about AutoLisp and VisualLisp on the Internet a didn't learn anything about it. Thanks again! Quote Link to comment Share on other sites More sharing options...
brianhiroshi Posted February 12, 2009 Author Share Posted February 12, 2009 Hi JohnM, I've tried your advice, but the AutoCAD returns an "error: too many arguments" message at the line "(ssadd (entlast ss1))". Would you know what could be the problem? Thanks again and sorry for bothering you guys. Quote Link to comment Share on other sites More sharing options...
brianhiroshi Posted February 12, 2009 Author Share Posted February 12, 2009 Another thing John, I may have fixed the "too many arguments problem" by doing this: At the beginning of the function, (setq ss1 (ssadd)) (setq el1 (entlast)) Then, after every line I've created, (ssadd el1 ss1) Then at the end, the lines... (command "._block" tipo pt1 "p" "" "") ;"tipo" is the name of the block the user entered (command "._insert" tipo pt1 "" "" "") But now there is a messge "No previous selection set"... Do you think what I did may be worng? Thanks again Quote Link to comment Share on other sites More sharing options...
JohnM Posted February 12, 2009 Share Posted February 12, 2009 The difference between autolisp and visual lisp is that autolisp is designed with it’s own list of functions like getstring , entget, vl-string-search and so on. Visual lisp is a way to utilize visual basic functions in autolisp. Open the lisp environment and than click on view then select apropos window. This will display a dialog box; in the text box you can enter a term to search for to see if there are any VLA functions available for it. Try typing the word line then click ok and you will see a list of stuff in the results box that has to do with the term line. Scroll down the list and anything with a vla in front of it is a visual basic function. Then you can highlight the item and click the? (Question mark) and the help file will open on that function. The help file is for visual basic users and is helpful but the actual vla function might be stated different in your code. So just copy the vla- function into google and typically you will find examples on how to implement it into your code. As far as the issues you’re having with the code I really need to see your code in order to trouble shoot it. My first posts where just thoughts and not tested so I’m not to surprised it has errors. If you could post or email me your code and we can fix it. Quote Link to comment Share on other sites More sharing options...
brianhiroshi Posted February 15, 2009 Author Share Posted February 15, 2009 Thank you very much for explaining. I think I'll have to learn more about programming before being able to use VLA functions About the code, it doesn´t belongs to me, I'm really sorry but I'm not aloud to post it anywhere even if it is were simple one. I've managed to do it selecting the lines by using a window drom a point to another with the block command, but I'm afraid that this may not be a good solution if I use the program into a more complex drawing. It may select entities that were not suposed to be part of the block. I'm sorry if I explain anything you didn't understand, my English is not that good. Do you think the "pedit" function could help? Thanks again and I'm really sorry I can't post the code. Quote Link to comment Share on other sites More sharing options...
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.