duke Posted April 28 Posted April 28 (edited) Hello people ! I am attaching a Routine that I made, quite "archaic", handmade, and I was wondering if there is a way to replace the SSGET / SSNAME with a more modern way of doing it? Or is that the only way to change attributes to all the ENTITIES of a group of Entities? In this Routine, I managed to exploit a block and all the elements within the block all have TRANSPARENCY 50 and the Routine sets their Transparency to "0" The Lisp attached is the same Routine As always, thank you very much in advance!! I am just learning the Lisp Language, and my intention was not to ensure that the Routine that I made myself does not work, but what I want is to learn more advanced commands, if they exist. Thank you !! ;@@@@@@@@@@@@@@@@@@ EXPLOTAR BLOQUES OSCUROS Y QUITARLES LO OSCURO @@@@@@@@@@@@@@@ (defun C:XX () (setq BLOQUE-A-EXPLOTAR-XX (entsel "\n Toca el BLOQUE a EXPLOTAR: ")) (command "EXPLODE" BLOQUE-A-EXPLOTAR-XX "") (setq OBJS-XX (ssget "P")) (setq SUMADOR-XX 0) (repeat (sslength OBJS-XX) (setq ENT-XX (ssname OBJS-XX SUMADOR-XX)) (setq OBJ-TEMP (vlax-ename->vla-object ENT-XX) ) ;@@@@@ Aqui saca el nombre de la LAYER de un Objeto (setq LAYER-OBJ-TEMP (vlax-get OBJ-TEMP 'Layer)) (command "LAYER" "M" LAYER-OBJ-TEMP "TR" "0" "" "") (setq SUMADOR-XX (1+ SUMADOR-XX)) ) ) XX para el FORO.lsp Edited April 28 by duke Quote
Steven P Posted April 28 Posted April 28 It all depends what you are ultimately wanting to do. In this example, it works, what is the problem? If it is a speed issue, that would only really become noticeable after thousands of objects in the selection set or many operations in the code. Some of the other programming languages might offer alternatives - I quite like LISP since it is built into CAD and interacts well with it Quote
duke Posted April 28 Author Posted April 28 3 minutes ago, Steven P said: It all depends what you are ultimately wanting to do. In this example, it works, what is the problem? If it is a speed issue, that would only really become noticeable after thousands of objects in the selection set or many operations in the code. Some of the other programming languages might offer alternatives - I quite like LISP since it is built into CAD and interacts well with it Hello, sorry for not clarifying, I am just learning the Lisp Language, and my intention was not to ensure that the Routine that I made myself does not work, but what I want is to learn more advanced commands, if they exist. Thank you !! Quote
Jonathan Handojo Posted April 28 Posted April 28 (edited) Hello duke, Welcome to the world of AutoLISP. Hopefully you will have a fun time learning it as you go. Just as Steven has pointed out, what you have done is the most common method of processing entities in a selection set. If anything, most programmers would simply reduce one more line by writing it like this: (repeat (setq i (sslength ss)) (setq i (1- i)) ;; Do your thing here ) Of course, there would be times when you would need to use a list instead of a selection set. In this case, you will need to convert them into a list first. Such functions are already available: SelectionSet to List. Edited April 28 by Jonathan Handojo 1 Quote
BIGAL Posted April 28 Posted April 28 (edited) Another when selecting objects. Makes VL objects. (if (= ss nil) (progn (Alert "Selection set was not created \n\n will now exit\n\nPlease check dwg and redo")(exit)) ) (repeat (setq i (sslength ss)) (setq obj (vlax-ename->vla-object (ssname ss (setq i (1- i))))) ;; Do your thing here ) Edited April 30 by BIGAL 1 Quote
duke Posted April 29 Author Posted April 29 3 hours ago, Jonathan Handojo said: Hello duke, Welcome to the world of AutoLISP. Hopefully you will have a fun time learning it as you go. Just as Steven has pointed out, what you have done is the most common method of processing entities in a selection set. If anything, most programmers would simply reduce one more line by writing it like this: (repeat (setq i (sslength ss)) (setq i (1- i)) ;; Do your thing here ) Of course, there would be times when you would need to use a list instead of a selection set. In this case, you will need to convert them into a list first. Such functions are already available: SelectionSet to List. INTERESANTE !!! Gracias por responder ! La unica duda q me queda es por qué razon se el resta un dígito, en lugar de sumar ? digo, para ir avanzando dentro de las entidades internas ======================================================== INTERESTING !!! Thank you for responding! The only question I have left is why does he subtract a digit, instead of adding? I mean, to move forward within the internal entities Quote
Jonathan Handojo Posted April 29 Posted April 29 45 minutes ago, duke said: INTERESANTE !!! Gracias por responder ! La unica duda q me queda es por qué razon se el resta un dígito, en lugar de sumar ? digo, para ir avanzando dentro de las entidades internas ======================================================== INTERESTING !!! Thank you for responding! The only question I have left is why does he subtract a digit, instead of adding? I mean, to move forward within the internal entities No worries. Glad to have you here. sslength return the length of the selection set. So setting the variable 'i' to the length of the selection set first means that we are processing items from the end of the selection set. Therefore, we need to decrement it from the end to the start. Hence why we are subtracting it. Most programs don't really take the order of processing into account, as long as all entities in the selection set are processed, that's all that matters. Quote
duke Posted April 29 Author Posted April 29 12 hours ago, Jonathan Handojo said: No hay problema. Me alegra tenerte aquí. sslength devuelve la longitud del conjunto de selección. Entonces, establecer primero la variable 'i' en la longitud del conjunto de selección significa que estamos procesando elementos desde el final del conjunto de selección. Por lo tanto, debemos disminuirlo desde el final hasta el principio. De ahí por qué lo estamos restando. La mayoría de los programas realmente no tienen en cuenta el orden de procesamiento, siempre que se procesen todas las entidades del conjunto de selección, eso es todo lo que importa. Ooooo si si qué bruto que soy ja ja, " i " es el numero MAYOR, por lo tanto hay q ir restando. Me encantó esa forma de hacerlo, lo aplicaré. Gracias por la paciencia !!! __________________ Ooooo yes yes how stupid I am ha ha, "i" is the LARGEST number, therefore you have to subtract. I loved that way of doing it, I will apply it. Thanks for the patience !!! Quote
duke Posted April 29 Author Posted April 29 21 hours ago, BIGAL said: Another when selecting objects. Makes VL objects. (if (= ss nil) (progn (Alert "Selection set was not created \n\n will now exit\n\nPlease check dwg and redo")(exit)) ) (repeat (setq i (sslength ss)) (setq obj (vlax-ename->vla-object (ssname ss (setq x (- x 1))))) ;; Do your thing here ) hI BRO, i am confused ha ha this line (setq x (- x 1)) where was created "x" ??? Or is (setq i (- i 1)) ))) Quote
exceed Posted April 30 Posted April 30 2 hours ago, duke said: hI BRO, i am confused ha ha this line (setq x (- x 1)) where was created "x" ??? Or is (setq i (- i 1)) ))) "i" is correct 1 Quote
BIGAL Posted April 30 Posted April 30 I thought i did an edit on the code yes should be I just me I use X all the time. 1 Quote
dexus Posted April 30 Posted April 30 (edited) I often use this helper function below to make it easier to go over a selection set: ;| ; Foreach-ss by dexus ; Loop over every item in a selectionset ; @Param input selection set ; @Param inputfunc function to execute over every item |; (defun foreach-ss (input inputfunc / n) (if (= 'PICKSET (type input)) (repeat (setq n (sslength input)) (inputfunc (ssname input (setq n (1- n)))) ) ) ) Can be used like this: (foreach-ss (ssget) (lambda (e) (princ (cdr (assoc 0 (entget e)))) ) ) Edited April 30 by dexus 2 Quote
duke Posted April 30 Author Posted April 30 9 hours ago, dexus said: I often use this helper function below to make it easier to go over a selection set: (defun foreach-ss (input inputfunc / n) (if (= 'PICKSET (type input)) (repeat (setq n (sslength input)) (inputfunc (ssname input (setq n (1- n)))) ) ) ) Can be used like this: (foreach-ss (ssget) (lambda (e) (princ (cdr (assoc 0 (entget e)))) ) ) i will try bro, thanks, your example looks beauty ‼‼‼‼ Quote
dexus Posted May 15 Posted May 15 I just found out that Vladimir Nesterovsky write a r-ss-foreach function back in 1997. https://vnestr.tripod.com/Revpline.lsp It's almost identical to my foreach-ss function, so not sure if we can call it "more modern commands" anymore . 2 Quote
duke Posted May 15 Author Posted May 15 5 hours ago, dexus said: I just found out that Vladimir Nesterovsky write a r-ss-foreach function back in 1997. https://vnestr.tripod.com/Revpline.lsp It's almost identical to my foreach-ss function, so not sure if we can call it "more modern commands" anymore . Thanks Dexus, i will try Quote
pkenewell Posted May 15 Posted May 15 (edited) How about something like this? ;; Performs a function on all items in a selection set. (defun mapss (ss func) (mapcar func (mapcar 'cadr (ssnamex ss))) ) ;; Test command. Returns a list of layers from the selection set. (defun c:test () (mapss (ssget "X") '(lambda (x)(cdr (assoc 8 (entget x))))) ) Edited May 15 by pkenewell 1 Quote
dexus Posted May 16 Posted May 16 Nice idea! A small improvement though. You want to remove all list items from ssnamex before processing. That is in case the items are selected with a box or lasso, which is information that ssnamex returns as well. ;; Performs a function on all items in a selection set. (defun mapss (ss func) (mapcar func (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)) ) ) ) 2 Quote
pkenewell Posted May 16 Posted May 16 6 hours ago, dexus said: A small improvement though. You want to remove all list items from ssnamex before processing. That is in case the items are selected with a box or lasso, which is information that ssnamex returns as well. Yes perfect! I started thinking and remembered that (ssnamex) doesn't always return the same list info last night and was planning to revisit this today. Good catch! 1 Quote
mhupp Posted May 16 Posted May 16 (edited) This is how I process a selection set. will generate a list of entity names for the selection (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))) ;code here will repeat for each each entity name in list ) A few years ago stumbled across what pkenewell posted to instead make a vla-object list (foreach obj (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))) ;code here will repeat for each each vla-object name in list ) ent and obj don't need to be declared since they are only temp while in the foreach loop. -edit @dexus The (vl-remove-if 'listp is to remove the point or points used when making the selection set this isn't needed when ssget with "_X" option is used. Since a pick point isn't generated for those selection sets. Edited May 16 by mhupp 2 Quote
dexus Posted May 17 Posted May 17 You're right mhupp, the mapss function wouldn't give an error in the "test command" pkenewell posted, but we do want these functions to work in most situations without throwing unexpected errors. Probably good to check if ss is really a pickset as well: (defun mapss (ss func) (if (= 'PICKSET (type ss)) (mapcar func (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)) ) ) ) ) Just to note, it is best to only use the mapss function when you need the output of the functions to be returned in a list. Otherwise your foreach loop or the foreach-ss function posted earlier would be preferable. 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.