Jump to content

removing deleted object from existing selection set


Trmsa

Recommended Posts

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

Link to comment
Share on other sites

  • Replies 25
  • Created
  • Last Reply

Top Posters In This Topic

  • Roy_043

    7

  • ronjonp

    5

  • Grrr

    5

  • Tharwat

    4

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 0

index 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 0

index 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! :)

Link to comment
Share on other sites

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. :ouch:

 

 

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

Later I somewhat understood with this example what happened when ssdel'ing an entity from a SS, while iterating thru the SS.

Link to comment
Share on other sites

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! :)
Link to comment
Share on other sites

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

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