JosephD Posted September 22, 2023 Posted September 22, 2023 Hello, I am trying to select only the items that my lisp program inserts (these consist of dynamic blocks and lines and such). I use the selection set to manipulate my templates but the problem arises when I have multiple templates of the same type in a single drawing, it modifies them all the same way. My thinking was I could create a selection set of all objects before the insert (setq ss1 (ssget "x")) and then create one after the insert that contains everything not in ss1. I am hoping this can be done in the creatin of a new selection set as opposed to modifying an existing one as I use (ssget "P" ;;;with additional modifiers ) before sending the set to my routines. The basic structure is as follows: (setq ss1 (ssget "x")) (command "insert" "*tmplate" pt "" "" "") (setq ss2 (ssget ;;;need help here) (setq ss (ssget "P" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blk))))) (MyFunction data1 data2 data3 ss) I need ss2 to contain everything in the drawing except what is in ss1 and it needs to be done in the creation so that ss will retrieve the correct set. I am still somewhat new to LISP so if there is another way to add the modifiers that are added for ss then that should allow for ss2 to be manipulated instead of correct on creation. Quote
Emmanuel Delay Posted September 25, 2023 Posted September 25, 2023 Yeah, that should work. I made you a function that will subtract the common items in 2 selection sets. And return the items in SS2 that are not also in ss1. Can you take it from here? Continue what you intended to do here (setq ss1 (ssget "x")) (command "insert" "*tmplate" pt "" "" "") .... (setq ss2 (ssget ;;;need help here) (setq ss3 (subtract_selection_sets ss2 ss1)) (sssetfirst nil ss3) ;; this grips the selection ;; returns ss2, which is ss2 - ss1 ;; any item in ss1 will cot be copied from ss2 to ss3 (defun subtract_selection_sets (ss2 ss1 / ss3 i j skip) (setq ss3 (ssadd)) (setq i 0) (repeat (sslength ss2) (setq j 0) (setq skip nil) (repeat (sslength ss1) (if (= ;; compare entity handles (cdr (assoc 5 (entget (ssname ss2 i)))) (cdr (assoc 5 (entget (ssname ss1 j)))) ) (progn (setq skip T) ) ) (setq j (+ j 1)) ) (if (= skip nil) (setq ss3 (ssadd (ssname ss2 i) ss3)) ) (setq i (+ i 1)) ) ss3 ) ;; Test 1. Test with selections you make manually. ;; Select a couple blocks. ;; Then select another couple block, make sure a few of the blocks are in both selections. ;; Those blocks in both selections will not be gripped/selected. (defun c:test1 ( / ss1 ss2 ss3) (princ "\nSelect first set: ") (setq ss1 (ssget (list (cons 0 "INSERT")))) (princ "\nSelect second set: ") (setq ss2 (ssget (list (cons 0 "INSERT")))) (setq ss3 (subtract_selection_sets ss2 ss1)) (sssetfirst nil ss3) ) Quote
Lee Mac Posted September 25, 2023 Posted September 25, 2023 Rather than comparing entity handles, you can simply use ssmemb, e.g.: (defun subtract_ss ( ss1 ss2 / ent idx ) (repeat (setq idx (sslength ss1)) (setq idx (1- idx) ent (ssname ss1 idx) ) (if (ssmemb ent ss2) (ssdel ent ss1)) ) ss1 ) Or, alternatively - (defun subtract_ss ( ss1 ss2 ) (vl-cmdf "_.select" ss1 "_r" ss2 "") (ssget "_p") ) 3 Quote
JosephD Posted September 25, 2023 Author Posted September 25, 2023 Thank you both for the quick response. I ended up using Lee's second function and it works like a charm. Much appreciated. 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.