Jump to content

Is there a way to simplify the "SSGET / SSNAME", perhaps with more modern commands?


duke

Recommended Posts

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 by duke
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 !!

Link to comment
Share on other sites

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 by Jonathan Handojo
  • Like 1
Link to comment
Share on other sites

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 by BIGAL
  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 !!!

Link to comment
Share on other sites

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))
)))

Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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 by dexus
  • Like 2
Link to comment
Share on other sites

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 ‼‼‼‼👌👌👌👌

Link to comment
Share on other sites

  • 2 weeks later...
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 

Link to comment
Share on other sites

Posted (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 by pkenewell
  • Like 1
Link to comment
Share on other sites

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))
    )
  )
)
  • Like 2
Link to comment
Share on other sites

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!

  • Like 1
Link to comment
Share on other sites

Posted (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 by mhupp
  • Like 2
Link to comment
Share on other sites

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.

  • Like 1
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...