bubba74 Posted December 17, 2009 Posted December 17, 2009 I just wanted to start off saying that I'm new to lisp and this forum and would appreciate any info. I use a dated architectural add-in called ArchT. It uses enhanced commands to move, copy, etc architectural objects. The application redefines stock autocad commands with their own enhanced versions to provide functionality with their own objects. Unfortunately Autocad crashes when any of these commands involve blocks with attributes. As a bandaid, I've written a lisp routine that will get a selection set and separate out all blocks with attributes and place them into a separate selection set. I was then hoping to move the blocks separately (and transparently) using ._copy or ._move. All of this would not require any more clicks or user input. This is when the problems begin.... I can not access ArchT's enhanced commands through autolisp because I believe they are lisp functions themselves. In other words, when I type (command "_move") it gives me an unknown command error. I can call the function (kti_archt_move) but it accepts no parameters and only allow user input (ie screen input). Is there any other way I can call this command? Could I create a macro that would pause for my selection set routine and then call the command I need? Sorry for being wordy, but I have seemed to hit a wall in every direction I turn. I am unsure about all the ins and outs of the i/o system for lisp. Any help would be greatly appreciated. Thanks Christian Quote
bubba74 Posted December 18, 2009 Author Posted December 18, 2009 Figured I would try to bump. Anyone have any ideas? Quote
jammie Posted December 18, 2009 Posted December 18, 2009 Hi I've written a lisp routine that will get a selection set and separate out all blocks with attributes and place them into a separate selection set Could you post a sample code of what you have written so far? I can not access ArchT's enhanced commands through autolisp because I believe they are lisp functions themselves You are probably correct with this Is there any other way I can call this command? For simple routines a work around can be achieved via a script file See http://www.cadtutor.net/forum/showthread.php?t=32685&page=2 http://www.cadtutor.net/forum/showthread.php?t=38450 Could you post a sample of the command line prompts for the (kti_archt_move) Regards Jammie Quote
wizman Posted December 18, 2009 Posted December 18, 2009 when you first select an object manually then initiate your custom ArchT command, does it process your pre-selected entities or does it ask you again for your selection set? Quote
JohnM Posted December 18, 2009 Posted December 18, 2009 try vla-move and vla-copy to bypass using the command call Quote
bubba74 Posted December 18, 2009 Author Posted December 18, 2009 Hi Jammie, here is the code to get the selection set and separate the objects: (setq SelMain(ssget)) (setq SelMainSize(sslength SelMain)) (setq SelBlock(ssadd)) (setq SelNoblock(ssadd)) (setq ctr 0) (while (< ctr (sslength SelMain)) (setq Ent(ssname SelMain ctr)) (setq EntData(entget Ent)) (if (assoc 66 EntData) (setq SelBlock(ssadd Ent SelBlock)) (setq SelNoblock(ssadd Ent SelNoblock)) ) (setq ctr(+ ctr 1)) ) (sssetfirst nil SelNoblock) Regarding the Archt commands, they mimic the stock autocad commands exactly. Here is what the archt move command does at the command line: Command: kti_archt_move Select objects: Specify opposite corner: 1 found Select objects: Base point or displacement: Second point of displacement: I'm not sure how to use scripts but I will look into this. Thanks! when you first select an object manually then initiate your custom ArchT command, does it process your pre-selected entities or does it ask you again for your selection set? Hi wizman, I tried what you said, and the command does work with the pre-selected object. try vla-move and vla-copy to bypass using the command call Hi John, I'm not sure how to use these (or vlisp for that matter), but I will read up on them. Thanks. Quote
Lee Mac Posted December 18, 2009 Posted December 18, 2009 These will help you with the Visual LISP: (defun v-move (ss p1 p2 / i ent) (vl-load-com) (setq i -1) (while (setq ent (ssname ss (setq i (1+ i)))) (vla-move (vlax-ename->vla-object ent) (vlax-3D-point p1) (vlax-3D-point p2))) ss) (defun v-copy (ss p1 p2 / i ent) (vl-load-com) (setq i -1) (while (setq ent (ssname ss (setq i (1+ i)))) (vla-move (vla-copy (vlax-ename->vla-object ent)) (vlax-3D-point p1) (vlax-3D-point p2))) ss) (defun c:test (/ ss pt1 pt2) (if (and (setq ss (ssget "_:L")) (setq pt1 (getpoint "\nFrom: ")) (setq pt2 (getpoint pt1 "\nTo: "))) (v-move ss pt1 pt2)) (princ)) "ss" is a SelectionSet, p1, p2 are points. Quote
bubba74 Posted December 18, 2009 Author Posted December 18, 2009 Hi Lee, Thanks for the vlisp code. Any help is greatly appreciated. I don't see how this can help me though. I need to be able to move certain objects through the ArchT routine so that I can retain ArchT object functionality. For example, I have walls with centerlines, windows, doors, etc. If I select a wall centerline through the ArchT command, the whole object moves along with the doors and windows in that wall. If I just use the standard move command, only the selected object moves and the assembly breaks. Quote
Lee Mac Posted December 18, 2009 Posted December 18, 2009 I was under the impression that you needed a workaround to move your separate selection set - the above code is your workaround. Quote
bubba74 Posted December 18, 2009 Author Posted December 18, 2009 I was under the impression that you needed a workaround to move your separate selection set - the above code is your workaround. Ah I see That part I was fairly comfortable with in lisp. Sorry if I am not explaining this properly. The problem I'm having is not being able to pass my modified selection set to the ArchT command. This is the step I need to prevent autocad from crashing. Once I accomplish this, then I think I can integrate your code to move the other selection set........or the obvious could just be flying over my head . Quote
jammie Posted December 18, 2009 Posted December 18, 2009 Hi Jammie, here is the code to get the selection set and separate the objects: Thanks Try the following as a starting point ;| Create an run a script file (create-script (list "tcircle" "l" "" "0.3" "r" "")) |; (defun create-script (<listCommands>) (vl-load-com) (setq fname (vl-filename-mktemp "test.scr") file (open fname "w")) (foreach n <listCommands> (write-line n file) ) (close file) (command "script" fname) (vl-file-delete fname) ) ;| Convert an point to a string for exporting to a script file eg (Pt2str '(10 20 0)) -> 10.000,20.000,0 |; (defun Pt2str (<Point> / x y z ) (setq X (rtos (car <Point>) 2 15) Y (rtos (cadr <Point>) 2 15) Z (rtos(caddr <Point>) 2 15) ) (strcat x "," y "," z) ) (defun c:test () (setq SelMain(ssget)) (setq SelMainSize(sslength SelMain)) (setq SelBlock(ssadd)) (setq SelNoblock(ssadd)) (setq ctr 0) (while (< ctr (sslength SelMain)) (setq Ent(ssname SelMain ctr)) (setq EntData(entget Ent)) (if (assoc 66 EntData) (setq SelBlock(ssadd Ent SelBlock)) (setq SelNoblock(ssadd Ent SelNoblock)) ) (setq ctr(+ ctr 1)) ) (sssetfirst nil SelNoblock) (if (and (setq Startpoint (getpoint "\nBase point :")) (setq Endpoint (getpoint Startpoint "\nSecond point of displacement: :")) ) (create-script (list "kti_archt_move" "p" ;previous selection set "" (Pt2str Startpoint) (Pt2str Endpoint) ) ) ) ) Quote
Lee Mac Posted December 18, 2009 Posted December 18, 2009 Nice idea Jammie, I've seen you use that before - only downside I can see is that the script takes control over the LISP But that may not be a problem in this situation. Quote
bubba74 Posted December 18, 2009 Author Posted December 18, 2009 HI Jammie and thanks for the start. I inputted your code and it seemed to crap out when the script was executed. This is what it looked like. Command: test Select objects: Specify opposite corner: 6 found Select objects: Base point : Second point of displacement: :nil Command: kti_archt_move This command may not be invoked transparently. Command: Command: p Unknown command "P". Press F1 for help. Quote
wizman Posted December 18, 2009 Posted December 18, 2009 How about: (sssetfirst nil (ssget '((-4 . "<or") (0 . "3DFACE,3DSOLID,ACAD_PROXY_ENTITY,ARC,ATTDEF,ATTRIB,BODY,CIRCLE,DIMENSION,ELLIPSE,HATCH,IMAGE,LEADER,LINE,LWPOLYLINE,MLINE,MTEXT,MULTILEADER,OLEFRAME,OLE2FRAME,POINT,POLYLINE,RAY,REGION,SEQEND,SHAPE,SOLID,SPLINE,TEXT,TOLERANCE,TRACE,VERTEX,VIEWPORT,XLINE") (-4 . "<AND") (0 . "INSERT") (66 . 0) (-4 . "AND>") (-4 . "or>") ) ) ;_ ssget ) ;_ sssetfirst ;; ;; (kti_archt_move) (sssetfirst nil (ssget '((0 . "INSERT")(66 . 1)) ) ;_ ssget ) ;_ sssetfirst ;; ;; (command "._move") Quote
wizman Posted December 18, 2009 Posted December 18, 2009 try also to add this to jammie's code, to invoke a lisp transparently: (vl-load-com) (vlax-add-cmd "kti_archt_move" 'kti_archt_move "kti_archt_move" 1) Quote
bubba74 Posted December 18, 2009 Author Posted December 18, 2009 Well I'm off for the weekend. I wanted to thank you guys for the help. I believe I have a solution. I'll post it next week when I have more time to test it. Quote
bubba74 Posted December 21, 2009 Author Posted December 21, 2009 I have got my move routine to work great. I didn't have to use scrips at all. All of your comments really helped me to see the solution. Here's the code if you're curious. (setq SelMain(ssget)) (setq SelBlock(ssadd)) (setq SelNoblock(ssadd)) (setq ctr 0) (while (< ctr (sslength SelMain)) (setq Ent(ssname SelMain ctr)) (setq EntData(entget Ent)) (if (assoc 66 EntData) (setq SelBlock(ssadd Ent SelBlock)) (setq SelNoblock(ssadd Ent SelNoblock)) ) (setq ctr(+ ctr 1)) ) (if (/= (sslength SelNoBlock) 0) (progn (setq TrackerPointData (entmake '((0 . "POINT")(8 . "TRACKER")(10 0.0 0.0 0.0)))) (setq TrackerPoint (entlast)) (setq pnt1 (cdr(assoc 10 TrackerPointData))) (setq SelNoblock(ssadd TrackerPoint SelNoblock)) (sssetfirst nil SelNoblock) (c:kti_archt_move) (setq TrackerPointData (entget TrackerPoint)) (setq pnt2 (cdr(assoc 10 TrackerPointData))) (entdel TrackerPoint) (command "_.purge" "LA" "TRACKER" "N") (if (/= (sslength SelBlock) 0) (command "._move" SelBlock "" pnt1 pnt2) ) ) (progn (sssetfirst nil SelBlock) (command "._move" "p" "") ) ) I basically create a temporary point to extract location info to move the block objects. Now I will tweak the code for my copy routine. Thanks guys! Quote
alanjt Posted December 21, 2009 Posted December 21, 2009 Just so you know, you can accomplish this with: (vla-sendcommand (vla-get-activedocument (vlax-get-acad-object)) "LINE ") Thanks Try the following as a starting point ;| Create an run a script file (create-script (list "tcircle" "l" "" "0.3" "r" "")) |; (defun create-script (<listCommands>) (vl-load-com) (setq fname (vl-filename-mktemp "test.scr") file (open fname "w")) (foreach n <listCommands> (write-line n file) ) (close file) (command "script" fname) (vl-file-delete fname) ) ;| Convert an point to a string for exporting to a script file eg (Pt2str '(10 20 0)) -> 10.000,20.000,0 |; (defun Pt2str (<Point> / x y z ) (setq X (rtos (car <Point>) 2 15) Y (rtos (cadr <Point>) 2 15) Z (rtos(caddr <Point>) 2 15) ) (strcat x "," y "," z) ) (defun c:test () (setq SelMain(ssget)) (setq SelMainSize(sslength SelMain)) (setq SelBlock(ssadd)) (setq SelNoblock(ssadd)) (setq ctr 0) (while (< ctr (sslength SelMain)) (setq Ent(ssname SelMain ctr)) (setq EntData(entget Ent)) (if (assoc 66 EntData) (setq SelBlock(ssadd Ent SelBlock)) (setq SelNoblock(ssadd Ent SelNoblock)) ) (setq ctr(+ ctr 1)) ) (sssetfirst nil SelNoblock) (if (and (setq Startpoint (getpoint "\nBase point :")) (setq Endpoint (getpoint Startpoint "\nSecond point of displacement: :")) ) (create-script (list "kti_archt_move" "p" ;previous selection set "" (Pt2str Startpoint) (Pt2str Endpoint) ) ) ) ) Quote
Lee Mac Posted December 21, 2009 Posted December 21, 2009 This may be more robust for you (defun c:test (/ v-move i ss selBlock SelnoBlock ent trck ) (defun v-move (ss p1 p2 / i ent) (vl-load-com) (setq i -1) (while (setq ent (ssname ss (setq i (1+ i)))) (vla-move (vlax-ename->vla-object ent) (vlax-3D-point p1) (vlax-3D-point p2))) ss) (if (setq i -1 ss (ssget "_:L")) (progn (setq SelBlock (ssadd) SelNoblock (ssadd)) (while (setq ent (ssname ss (setq i (1+ i)))) (if (assoc 66 (entget ent)) (ssadd ent selblock) (ssadd ent selnoblock))) (if (not (zerop (sslength selnoblock))) (progn (setq trck (entmakex '((0 . "POINT") (10 0 0 0)))) (sssetfirst nil selnoblock) (c:kti_archt_move) (if (not (zerop (sslength selblock))) (v-move selblock '(0 0 0) (cdr (assoc 10 (entget trck))))) (entdel trck)) (command "_.move" selblock "" pause pause)))) (princ)) { untested } Quote
bubba74 Posted December 21, 2009 Author Posted December 21, 2009 Sorry, I have no experience with visual lisp. Why does this benefit me? 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.