I haven't been actively coding for a few years, so I'm really rusty. How can I test a large selection set to see if the user selected only the right type of entities? My idea is as follows:
(setq PNT_SET (ssget)) (cond ((null PNT_SET) (progn ;;selection set is empty (alert "No entities selected.\n Function cancelled.") (princ) (exit) ) ) ((= PNT_SET <<<A LIST COMPOSED ENTIRELY OF POINT ENTITIES>>>) (setq PNT_SET_IS_BLOCKS nil PNT_SET_IS_POINTS T) ;;selection set is made up of point entities ) ((= PNT_SET <<<A LIST COMPOSED ENTIRELY OF BLOCKS NAMED "foo">>>) (setq PNT_SET_IS_POINTS nil PNT_SET_IS_BLOCKS T) ;;selection set is made up of blocks named "foo" ) (T (progn ;;selection set is not points or blocks named "foo" (alert "Invalid entities selected.\n Function cancelled.") (princ) (exit) ) ) )
Thanks for any help!
If the user is being prompted to select objects, I would use filters on the (ssget...) call so they could only select the required object types. Otherwise, you would iterate the selection set and test the object type of each entity in the set, building a side-selection set or list as you go.
A question: For the fall-back fourth (T) condition, as I understand the conditions prior to that, the description should say:
;;selection set is neither all & only points nor all & only blocks named "foo"
If it contains some of each, or some of either or both and some other object type(s), then it wouldn't fit the <<...ENTIRELY OF...>> aspect of the prior conditions. Is it the intent that a set like that would be considered an entirely invalid selection, just as much as one that didn't contain any of either type?
For the second and third conditions, an approach could be to make a list of the entity names out of the selection set, then use (vl-remove-if) on that list, with a testing function looking for the particular entity type or Block name. If that list gets wiped out, then the selection was entirely of that kind of thing, because they were all removed from the list. Or you could use (fl-remove-if-not), and if the resulting list is the same length as the original, they were all the right kind.
I agree that selection-set filtering is a good way to begin. With that, conditions can be nothing-selected, only points, only Blocks named "foo", and the fallback specifically a mixture of the two and nothing else. A selection that contains only other kinds of things would fall into the first condition, because the filtering will not accept those others.
Another approach, only for testing purposes
(defun c:test (/ PNT_SET SS) (if (setq PNT_SET (ssget (list '(-4 . "<OR") '(-4 . "<AND") '(0 . "POINT") '(-4 . "AND>") '(-4 . "<AND") '(0 . "INSERT") '(2 . "foo") '(-4 . "AND>") '(-4 . "OR>") );; filtering only points and blocks named foo ) ) (progn (if (setq ss (ssget "_P" '((0 . "POINT"))));; if there are points in the first selection set (progn (if (= (sslength PNT_SET) (sslength ss));; testing if the number of entities is the same (alert "Selection set is made up of point entities!");; if true (alert "Selection set is a mix of points and blocks named <foo>!");; if not true );; if );; progn (alert "Selection set is made up of blocks named \"foo\"!");; if there are no points in the first selection set );; if );; progn (alert "No entities selected.\n Function cancelled.");; if nothing selected );; if );; test
HTH
Henrique
Or perhaps something along the lines of:
(defun c:test ( / sel ) (while (if (setq sel (ssget '( (-4 . "<OR") (0 . "POINT") (-4 . "<AND") (0 . "INSERT") (2 . "FOO") (-4 . "AND>") (-4 . "OR>") ) ) ) ( (lambda ( / idx lst ) (repeat (setq idx (sslength sel)) (setq lst (cons (cdr (assoc 0 (entget (ssname sel (setq idx (1- idx)))))) lst)) ) (cond ( (apply '= (cons "POINT" lst)) (prompt "\nPoints selected.") ) ( (apply '= (cons "INSERT" lst)) (prompt "\nBlocks selected.") ) ( (princ "\nInvalid selection.")) ) ) ) (prompt "\Nothing selected.") ) ) (princ) )
Thank you, one and all! As I said, I'm rusty - but when I do have the opportunity to do some programming I like to use clean code.
As far as my immediate needs, I will be the only user so I can assume fewer issues with wrong entities in the selection set. I will play around with each of your suggestions, and learn a bit more in the process.
As always the assistance in this forum is first-rate and much appreciated!
Dean
You're most welcome Dean, thanks!