flopo Posted July 1, 2011 Share Posted July 1, 2011 Hello guys, I have a lisp (loo.lsp), found here on this site, that allow me to select last n entities drawn. I wrote my own lisp (curve.lisp) to draw piping objects - curves. I want to insert loo.lsp in curve.lsp to be able to move all the objects drawn with curve.lsp - (13 objects, lines and arcs - in this case). Any help, please? Thanks! CURVE.LSP (defun c:CURVE () (setq DIA (getreal "\nDN :")) (setq RC (getreal "\nRadius :")) (SETQ UNGHI(getreal "\nAngle :")) (SETQ ANG (/ (* UNGHI pi ) 180)) (SETQ ANG/2 (* ANG 0.5)) (defun DTR (deg) (* deg (/ PI 180))) (if (= dia 50)(setq di 0.0603)) (if (= dia 80)(setq di 0.0889)) (if (= dia 100)(setq di 0.1143)) (if (= dia 150)(setq di 0.1683)) (if (= dia 200)(setq di 0.2190)) (if (= dia 250)(setq di 0.273)) (if (= dia 300)(setq di 0.3239)) (if (= dia 350)(setq di 0.3556)) (if (= dia 400)(setq di 0.4064)) (if (= dia 450)(setq di 0.4572)) (if (= dia 500)(setq di 0.508 )) (if (= dia 600)(setq di 0.6096)) (if (= dia 700)(setq di 0.710)) (if (= dia 800)(setq di 0.813)) (if (= dia 900)(setq di 0.914)) (setq PCEN (getpoint "\nCenter point:")) (SETQ PC1 (POLAR PCEN (DTR 270) (+ RC (/ DI 2)))) (SETQ PC2 (POLAR PC1 (DTR 180) 0.5)) (SETQ PC3 (POLAR PC2 (DTR 90) DI)) (SETQ PC4 (POLAR PC1 (DTR 90) DI)) (SETQ PCI1 (POLAR PC1 (DTR 90) (/ DI 2))) (SETQ DPCIPCI1 (* RC ( / (SIN ANG/2) (COS ANG/2)))) (setq PCI (POLAR PCI1 (DTR 0) DPCIPCI1)) (setq PCI2 (POLAR PCI (DTR UNGHI) DPCIPCI1)) (setq PC5 (POLAR PCI2 (DTR (+ 270 UNGHI)) (/ DI 2))) (setq PC6 (POLAR PC5 (DTR UNGHI) 0.5)) (setq PC7 (POLAR PC6 (DTR (+ 90 UNGHI)) DI)) (setq PC8 (POLAR PCI2 (DTR (+ 90 UNGHI)) (/ DI 2))) (SETQ PCI11 (POLAR PCI1 (DTR 180) 0.5)) (SETQ PCI22 (POLAR PCI2 (DTR UNGHI) 0.5)) (COMMAND "CLAYER" "CONTUR" ) (COMMAND "-COLOR" "BYLAYER" "") (COMMAND "LINE" PC1 PC2 PC3 PC4 PC1 "" ) (COMMAND "LINE" PC5 PC6 PC7 PC8 PC5 "" ) (COMMAND "ARC" "C" PCEN PC4 PC8 "") (COMMAND "ARC" "C" PCEN PC1 PC5 "") (COMMAND "CLAYER" "AXE" ) (COMMAND "-COLOR" "BYLAYER" "") (COMMAND "ARC" "C" PCEN PCI1 PCI2 "") (COMMAND "LINE" PCI11 PCI1 "" ) (COMMAND "LINE" PCI2 PCI22 "" ) ;(command "loo" 13) .....???????? ;(command "move" "p" .......??????????? (princ)) LOO.LSP (defun lastn (INT2 / SS2 SSL2) ;define function to take 1 argument (setq SS2 (ssadd)) ;set SS2 to an empty selection set (repeat INT2 ;repeat INT2 times (if (entlast) (progn (ssadd (entlast) SS2) ;add last undeleted object to selection set (entdel (entlast)) ;delete last undeleted object ) ) ) (setq SSL2 (1- (sslength SS2)));set SSL2 to 1 less than size of selection set (while (>= SSL2 0) ;while SSL2 is greater than or equal to zero (entdel (ssname SS2 SSL2)) ;undelete SSL2'th object in selection set (setq SSL2 (1- SSL2)) ;decrement SL2 ) SS2 ;return selection set to calling function ) ;end (lastn) function (defun C:loo (/ COUNT2) ;define function ;set COUNT2 to number of objects (setq COUNT2 (getint "\nEnter number of objects: ")) (if (= 0 (getvar "CMDACTIVE")) ;if no other command is active (progn ;else (command "._SELECT" (lastn COUNT2) "") ;run SELECT command and (lastn) (princ) ;exit quietly ) (lastn COUNT2) ;call (lastn) function with argument ) ) Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 1, 2011 Share Posted July 1, 2011 Flopo - First, please remember to use tags (<- without the space) when posting code. You can do so by hitting the [b]#[/b] button on the toolbar. As for your request, since loo.lsp is defined as "lastn" and accepts a single argument "INT2" (an integer): [code] (defun [color="red"]lastn[/color] (INT2 / SS2 SSL2) ;define function to take 1 argument You can invoke this function from your curve.lsp like so: (setq myCurveItems (lastn <integer>)) ... Where represents the sum of the entities created during your curve.lsp function. Be sure to call (entlast) during curve.lsp before creating any items, and for each item created increment (1+) a stored variable counter which can be passed to "lastn" as shown above. However, IMO, you could simplify this by instead storing each item created to a selection set (using ssadd), then invoking the move command on said selection set, rather than stepping through "lastn" at all. Just a thought. Also, to offer some constructive criticism (if I may), perhaps you could simplify your curve.lsp code some. One example of this would to be to consider replacing the series of if statements, with a single cond statment: ... (setq DIA (getreal "\nDN :")) ... (if (= dia 50)(setq di 0.0603)) (if (= dia 80)(setq di 0.0889)) (if (= dia 100)(setq di 0.1143)) (if (= dia 150)(setq di 0.1683)) (if (= dia 200)(setq di 0.2190)) (if (= dia 250)(setq di 0.273)) (if (= dia 300)(setq di 0.3239)) (if (= dia 350)(setq di 0.3556)) (if (= dia 400)(setq di 0.4064)) (if (= dia 450)(setq di 0.4572)) (if (= dia 500)(setq di 0.508 )) (if (= dia 600)(setq di 0.6096)) (if (= dia 700)(setq di 0.710)) (if (= dia 800)(setq di 0.813)) (if (= dia 900)(setq di 0.914)) ... (cond ((= 50 dia) (setq di 0.0603)) ((= 80 dia) (setq di 0.0889)) ; <- More options here ) Hope this helps! Quote Link to comment Share on other sites More sharing options...
irneb Posted July 2, 2011 Share Posted July 2, 2011 (edited) Another option (if you don't know beforehand how many entities will get drawn) is to save the entlast to a global variable. Then run the code. After which check if there are any entnext entities after that one you saved. E.g.: (defun c:StoreLast (/ ) (setq *LastEnt* (entlast)) (princ)) (defun c:ClearLast (/ ) (setq *LastEnt* nil) (princ)) (defun c:CheckLast (/ en ss) (setq ss (ssadd)) (if (setq en (entnext *LastEnt*)) (while en (setq ss (ssadd en ss) en (entnext en)) ) ) (sssetfirst nil ss) (princ (strcat "There were " (itoa (sslength ss)) " entities created. They're now selected.")) (princ) ) With this you type StoreLast just before running your code(s). Then you type CheckLast and it displays how many entities were created and selects them. BTW, I've made something similar to this a while ago. It's called 'Result selection. Attached file. It needs to be loaded at the start (I usually just have it loading through acaddoc.lsp or an MNL file or whatever means). Then you should have a new command RESULT which you can issue transparently by prefixing a single quote 'RESULT. This allows you to select the entities created in any of the previous 5 commands. If you want more then modify the number stored to the $Result-Length variable on the 19th line in the lisp. Edit: I really need to start looking at some standardization of my lisp variable/function naming! Just realized how my "preferences" have adjusted themselves over the years when I noticed the $ prefix selresult.lsp Edited July 2, 2011 by irneb Quote Link to comment Share on other sites More sharing options...
irneb Posted July 2, 2011 Share Posted July 2, 2011 Flopo, I'd rather reply in this thread than the PM. Perhaps someone else could also then learn. (defun c:CURVE ([color=red]/ DIA RC UNGHI ANG ANG/2 DTR di _LastEnt_ ss en[/color]) [color=red](setq _LastEnt_ (entlast)) ;Added by Irné Barnard[/color] (setq DIA (getreal "\nDN :")) (setq RC (getreal "\nRadius :")) (SETQ UNGHI (getreal "\nAngle :")) (SETQ ANG (/ (* UNGHI pi) 180)) (SETQ ANG/2 (* ANG 0.5)) (defun DTR (deg) (* deg (/ PI 180))) (if (= dia 50) (setq di 0.0603) ) (if (= dia 80) (setq di 0.0889) ) (if (= dia 100) (setq di 0.1143) ) (if (= dia 150) (setq di 0.1683) ) (if (= dia 200) (setq di 0.2190) ) (if (= dia 250) (setq di 0.273) ) (if (= dia 300) (setq di 0.3239) ) (if (= dia 350) (setq di 0.3556) ) (if (= dia 400) (setq di 0.4064) ) (if (= dia 450) (setq di 0.4572) ) (if (= dia 500) (setq di 0.508) ) (if (= dia 600) (setq di 0.6096) ) (if (= dia 700) (setq di 0.710) ) (if (= dia 800) (setq di 0.813) ) (if (= dia 900) (setq di 0.914) ) (setq PCEN (getpoint "\nCenter point:")) (SETQ PC1 (POLAR PCEN (DTR 270) (+ RC (/ DI 2)))) (SETQ PC2 (POLAR PC1 (DTR 180) 0.5)) (SETQ PC3 (POLAR PC2 (DTR 90) DI)) (SETQ PC4 (POLAR PC1 (DTR 90) DI)) (SETQ PCI1 (POLAR PC1 (DTR 90) (/ DI 2))) (SETQ DPCIPCI1 (* RC (/ (SIN ANG/2) (COS ANG/2)))) (setq PCI (POLAR PCI1 (DTR 0) DPCIPCI1)) (setq PCI2 (POLAR PCI (DTR UNGHI) DPCIPCI1)) (setq PC5 (POLAR PCI2 (DTR (+ 270 UNGHI)) (/ DI 2))) (setq PC6 (POLAR PC5 (DTR UNGHI) 0.5)) (setq PC7 (POLAR PC6 (DTR (+ 90 UNGHI)) DI)) (setq PC8 (POLAR PCI2 (DTR (+ 90 UNGHI)) (/ DI 2))) (SETQ PCI11 (POLAR PCI1 (DTR 180) 0.5)) (SETQ PCI22 (POLAR PCI2 (DTR UNGHI) 0.5)) (COMMAND "CLAYER" "CONTUR") (COMMAND "-COLOR" "BYLAYER" "") (COMMAND "LINE" PC1 PC2 PC3 PC4 PC1 "") (COMMAND "LINE" PC5 PC6 PC7 PC8 PC5 "") (COMMAND "ARC" "C" PCEN PC4 PC8 "") (COMMAND "ARC" "C" PCEN PC1 PC5 "") (COMMAND "CLAYER" "AXE") (COMMAND "-COLOR" "BYLAYER" "") (COMMAND "ARC" "C" PCEN PCI1 PCI2 "") (COMMAND "LINE" PCI11 PCI1 "") (COMMAND "LINE" PCI2 PCI22 "") ;; Not needed: (command "loo" 13) .....???????? [color=red];; Added by Irné Barnard ;; Create a selection set to send to the move command (setq ss (ssadd)) (if (setq en (entnext _LastEnt_)) ;Check if there's a new entity created sinse the last one (while en ;Step through all new entities (setq ss (ssadd en ss) ;Add it to the selection set en (entnext en) ;Get the next entity ) ) )[/color] ;; Modified by Irné Barnard (command "[color=red]_.[/color]move" [color=red]ss ""[/color]) (princ) ) I've opted to go with the save lastent idea instead. That select result thing is a much more comlpex piece of code which works with any command in acad - not as simple to use inside a lisp routine. BTW, I wanted to also add your variables as local ... but gave up after the 1st handful. It's always a good idea to localize your lisp variables. Though with so many this becomes a pain! Could you try to reuse some variables in the code instead of making a new one every time? It might also help reduce your code's RAM requirements. Edit: Just to be pedantic on myself ... that ssadd doesn't need to be setq'd. It actually modifies the selection set instead of creating a new one. So this should perform exactly the same: (setq ss (ssadd)) (if (setq en (entnext _LastEnt_)) ;Check if there's a new entity created sinse the last one (while en ;Step through all new entities (ssadd en ss) ;Add it to the selection set (setq en (entnext en)) ;Get the next entity ) ) And here I go again with these prefixes and suffixes! Now it's underscores! WTF? I think I've got a split personality! Anyone heard me speak in a different voice recently? Quote Link to comment Share on other sites More sharing options...
flopo Posted July 2, 2011 Author Share Posted July 2, 2011 Thanks, perfect! Quote Link to comment Share on other sites More sharing options...
BIGAL Posted July 3, 2011 Share Posted July 3, 2011 Just another suggestion it looks like you will probably write more routines that involve the dia of pipes I would pull the Cond dia size to a seperate defun that is autoloaded this way any future routine can take advantage of it, also if you get new pipes you only have to add to one routine. eg 450p 450s 450g plastic, steel, glass reo. (getnewdia dia) returns DI Quote Link to comment Share on other sites More sharing options...
irneb Posted July 3, 2011 Share Posted July 3, 2011 Yes, as you make more of these defuns, you'll notice you constantly type the same things over and over again. That's usually a good time to start looking at creating some library functions - so you can simply call them instead of rewriting / copy-n-pasting. I'm glad it works for you though. Happy Lisping! 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.