Jump to content

Combine 2 lisps to select last n entities drawn


flopo

Recommended Posts

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

)

)

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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 :shock:

selresult.lsp

Edited by irneb
Link to comment
Share on other sites

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 o:) ... 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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...