Grrr Posted October 21, 2017 Share Posted October 21, 2017 The key here is that Tharwat's code starts with the *last* entity in the set. That is why it succeeds as opposed to the OP's code. It can if you are not careful. Proceeding through the selset going forward, you cannot simply increment the index number. In the repeat function, if you either increase the index number OR delete the entity from the selection set, it will work just fine, but will be less hassle to just proceed backward through the selset (like tharwat did). If the entities that are erased are erased via lisp (theoretically it is (unless the selset is global?)), another approach would be to ssdel the entity from the selset as the entity is erased, skipping altogether the need to process once more through the selset. Thans for answering guys, I did a quick test to check on the results (commented 4 you) : (defun C:test ( / genpt SS i e enx ) ; From a blank dwg, generate 10 points with different colors, and include them in a SS (defun genpt ( c / ) (entmakex (list '(0 . "POINT")(cons 62 c) '(10 0. 0. 0.)))) ((lambda ( / n ) (setq n 0) (repeat 10 (genpt (setq n (1+ n)))))) (setq SS (ssget "_X" '((0 . "POINT")))) (setq i -1) ; Determine which SS iteration fails [comment the other two]: ; #1 (while (setq e (ssname SS (setq i (1+ i)))) ; while = straight repeat (setq enx (entget e)) (and (member i '(2 6)) (ssdel e SS)) ); while ; #2 (repeat (setq i (sslength SS)) ; reverse repeat (setq e (ssname SS (setq i (1- i)))) (setq enx (entget e)) (and (member i '(2 6)) (ssdel e SS)) ); repeat ; #3 (repeat (sslength SS) ; straight repeat (setq e (ssname SS (setq i (1+ i)))) (setq enx (entget e)) (and (member i '(2 6)) (ssdel e SS)) ); repeat ; Check the results, points with index colours 2 and 6 shall stay on '(0 0 0) (sssetfirst nil SS) (command "_.move" SS "" "_non" '(0. 0. 0.) "_non" '(0. 50. 0.)) (princ) ); defun Looks like it depends on the entity creation order - inside the SS they are sorted by their handles (I guess). So with the while iteration I'm left with points #3 and #8 unmoved (something is fishy). Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted October 22, 2017 Share Posted October 22, 2017 Nothing is fishy. Please check the actual order of the set. Quote Link to comment Share on other sites More sharing options...
Jef! Posted October 23, 2017 Share Posted October 23, 2017 Thans for answering guys, I did a quick test to check on the results (commented 4 you) : (defun C:test ( / genpt SS i e enx ) ; From a blank dwg, generate 10 points with different colors, and include them in a SS (defun genpt ( c / ) (entmakex (list '(0 . "POINT")(cons 62 c) '(10 0. 0. 0.)))) ((lambda ( / n ) (setq n 0) (repeat 10 (genpt (setq n (1+ n)))))) (setq SS (ssget "_X" '((0 . "POINT")))) (setq i -1) ; Determine which SS iteration fails [comment the other two]: ; #1 (while (setq e (ssname SS (setq i (1+ i)))) ; while = straight repeat (setq enx (entget e)) (and (member i '(2 6)) (ssdel e SS)) ); while ; #2 (repeat (setq i (sslength SS)) ; reverse repeat (setq e (ssname SS (setq i (1- i)))) (setq enx (entget e)) (and (member i '(2 6)) (ssdel e SS)) ); repeat ; #3 (repeat (sslength SS) ; straight repeat (setq e (ssname SS (setq i (1+ i)))) (setq enx (entget e)) (and (member i '(2 6)) (ssdel e SS)) ); repeat ; [b]Check the results, points with index colours 2 and 6 shall stay on[/b] '(0 0 0) (sssetfirst nil SS) (command "_.move" SS "" "_non" '(0. 0. 0.) "_non" '(0. 50. 0.)) (princ) ); defun Looks like it depends on the entity creation order - inside the SS they are sorted by their handles (I guess). So with the while iteration I'm left with points #3 and #8 unmoved (something is fishy). You are mixing things... look at your processing (and (member i '(2 6)) (ssdel e SS)) i is your index number, and if your index number is 2 or 6 you remove it from the selection set. It has nothing to do with the color. You setq enx by entgeting e, but dont do anything with enx. As for the index shifting, I already explained that here. Ill adapt with your situation. Lets say you are looking to ssdel color 2 index 0 object color 0index 1 object color 1 index 2 object color 2 index 3 object color 3 index 4 object color 4 counter set to 0... you retrieve index 0, object with color 0, leave it, increase the counter by one, counter is now set to 1... you retrieve index 1, object with color 1, leave it, increase the counter by one, counter is now set to 2... you retrieve index 2, object with color 2, and delete it from the selection set, increase the counter by one, counter is now set to 3... After deleting an entry in the selection set, it now looks like that index 0 object color 0index 1 object color 1 index 2 object color 3 index 3 object color 4 After that you retrieve index 3, which is object with color 4, and just skipped object with color 3 due to the fact that you systematically increment index. If you ssdel processing forward, you must skip the index incrementing and retrieve the same index # again due to the shift you create by using ssdel. Increment index counter OR ssdel. In your exemples you ssdel index 2. Then ssdel index 6 of the "new 9 items selset", so it actually removes items index 2 and 7 from the original selection set... which are point #3 and #8. Hope it clarified things for you. Cheers! Quote Link to comment Share on other sites More sharing options...
Grrr Posted October 23, 2017 Share Posted October 23, 2017 You are mixing things... look at your processing(and (member i '(2 6)) (ssdel e SS)) i is your index number, and if your index number is 2 or 6 you remove it from the selection set. It has nothing to do with the color. Thats the point Jef: I'm trying to remove by index number and accordingly to perform manual checking on the colors to see which indexes were moved. You setq enx by entgeting e, but dont do anything with enx. I've forgot to erase that. counter set to 0... you retrieve index 0, object with color 0, leave it, increase the counter by one, counter is now set to 1... you retrieve index 1, object with color 1, leave it, increase the counter by one, counter is now set to 2... you retrieve index 2, object with color 2, and delete it from the selection set, increase the counter by one, counter is now set to 3... After deleting an entry in the selection set, it now looks like that After that you retrieve index 3, which is object with color 4, and just skipped object with color 3 due to the fact that you systematically increment index. If you ssdel processing forward, you must skip the index incrementing and retrieve the same index # again due to the shift you create by using ssdel. Increment index counter OR ssdel. In your exemples you ssdel index 2. Then ssdel index 6 of the "new 9 items selset", so it actually removes items index 2 and 7 from the original selection set... which are point #3 and #8. Hope it clarified things for you. Cheers! Thanks Jef, now everything is clear as a glass of untouched vodka! Later I somewhat understood with this example what happened when ssdel'ing an entity from a SS, while iterating thru the SS. Quote Link to comment Share on other sites More sharing options...
Jef! Posted October 23, 2017 Share Posted October 23, 2017 Good!. I see that since you ssdel everything you kept grabbing ssname 0. For that kind of thing it is more efficient to avoid using ssdel, as the whole index is updated n times, n being the number of items in the selset. the added delay getting exponentially bigger as the selection set is bigger. For few items it is not that bad, but if the selset has few thousands objects, it might let you hanging few seconds. Not the best practice. I personally use ssdel only when I remove some items from an existing selset, and I know that 1- I wont need the original selset anymore and 2- I will need to use the partial selset further down. Thanks Jef, now everything is clear as a glass of untouched vodka! Glad I could help! Quote Link to comment Share on other sites More sharing options...
Grrr Posted October 23, 2017 Share Posted October 23, 2017 Yeah, I avoid ssdel too - just decided to investigate it this time (I know its inefficient since I've read this). Worn out using the reverse repeat iteration and played/explored with recursions at one time. Perhaps this one would be the most inefficient way to process(map to) a selection set: ; (MapSS (lambda (x) (cdr (assoc 8 (entget e)))) (ssget)) (defun MapSS ( f SS / e ) (if (setq e (ssname SS 0)) (cons (f e) (progn (ssdel e SS) (MapSS f SS)) ) ) ) Quote Link to comment Share on other sites More sharing options...
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.