TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: qwrtz on April 24, 2015, 12:06:46 PM

Title: Selection by Handle greater than
Post by: qwrtz on April 24, 2015, 12:06:46 PM
I want to execute a command within a lisp routine, and then select all entities created by the command.

I know I can get the handle of the last entity created before the command:
Code - Auto/Visual Lisp: [Select]
  1. (setq Handle1 (cdr (assoc 5 (entget (entlast)))))

After the command I should be able to use (ssget "X") to select all entities with a handle greater than Handle1, but I've tried a lot of things and can't find code that works.

Can anyone help me? Logical operators always confuse me, and I'm not that good with filter lists either, but I think this would probably be very simple for many people on this forum.
Title: Re: Selection by Handle greater than
Post by: ronjonp on April 24, 2015, 12:10:02 PM
I want to execute a command within a lisp routine, and then select all entities created by the command.
...
You could just keep track of the entities you're creating in your routine, then you don't have to select them again?
BTW .. welcome to TheSwamp :)
Title: Re: Selection by Handle greater than
Post by: MP on April 24, 2015, 12:25:58 PM
Code: [Select]
(defun _SSAfter ( ename / ss d e )

    (if (eq 'ename (type ename))
        (progn
            (setq
                ss (ssadd)
                e  (entnext ename)
            )
            (while e
                (if
                    (and
                        (setq d (entget e))
                        (null (member (cdr (assoc 0 data)) '("VERTEX" "ATTRIB" "SEQEND")))
                    )
                    (ssadd e ss)
                )
                (setq e (entnext e))
            )
            (if
                (and
                    (eq 'pickset (type ss))
                    (< 0 (sslength ss))
                )
                ss
            )
        )
    )
)

Syntax:

(setq ss (_ssafter some_ename))

Edit: Revised to harvest only prime entities.
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 24, 2015, 12:32:21 PM
As noted in the documentation (http://exchange.autodesk.com/autocad/enu/online-help/browse#WS73099cc142f4875516d84be10ebc87a53f-7a31.htm), you cannot use an ssget filter list to filter for the DXF handle group 5.

Instead, I would suggest retrieving the last entity in the database before issuing your command, and then stepping through all entities created by the command by using entnext to step through the drawing database one entity at a time.

You can retrieve the last entity added to the database using the following function:
Code - Auto/Visual Lisp: [Select]
  1. (defun lastent ( / rtn tmp )
  2.     (setq rtn (entlast))
  3.     (while (setq tmp (entnext rtn)) (setq rtn tmp))
  4.     rtn
  5. )

You can then step over the entities created by the command in the following way:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / ent new )
  2.     (setq ent (lastent)
  3.           new (ssadd)
  4.     )
  5.     (command
  6.         "_.line"   "_non" '(0 -1) "_non" '(0 1) ""
  7.         "_.line"   "_non" '(-1 0) "_non" '(1 0) ""
  8.         "_.circle" "_non" '(0  0) 0.5
  9.     )
  10.     (while (setq ent (entnext ent))
  11.         (ssadd ent new)
  12.     )
  13.     (sssetfirst nil new)
  14.     (princ)
  15. )

In before MP :P
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 24, 2015, 12:36:26 PM
Further to the above, to account for subentities (excluding them from the resulting set):
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / ent new )
  2.     (setq ent (lastent)
  3.           new (ssadd)
  4.     )
  5.     (command
  6.         "_.line"   "_non" '(0 -1) "_non" '(0 1) ""
  7.         "_.line"   "_non" '(-1 0) "_non" '(1 0) ""
  8.         "_.circle" "_non" '(0  0) 0.5
  9.     )
  10.     (while (setq ent (entnext ent))
  11.         (ssadd ent new)
  12.         (if (= 1 (cdr (assoc 66 (entget ent))))
  13.             (while (/= "SEQEND" (cdr (assoc 0 (entget ent))))
  14.                 (setq ent (entnext ent))
  15.             )
  16.         )
  17.     )
  18.     (sssetfirst nil new)
  19.     (princ)
  20. )
Title: Re: Selection by Handle greater than
Post by: David Bethel on April 24, 2015, 01:16:41 PM
I don't think you can use handles in a ( ssget ) filter.  I'll look

From 2004 autolisp help -> ssget

Quote
An entity filter list is an association list that uses DXF group codes in the same format as a list returned by entget. (See the DXF Reference for a list of group codes.) The ssget function recognizes all group codes except entity names (group –1), handles (group 5), and xdata codes (groups greater than 1000). If an invalid group code is used in a filterlist, it is ignored by ssget.
Title: Re: Selection by Handle greater than
Post by: dgorsman on April 24, 2015, 01:20:22 PM
Alternatively, create a selection set before and after modification; the delta between the two will be whatever was added.  But first priority would be for actively logging entities as they were created.
Title: Re: Selection by Handle greater than
Post by: roy_043 on April 24, 2015, 05:21:24 PM
@ MP:
You are probably using (entget e) in your code to check if the entity has not been erased.
It is my understanding that (entnext) does not find erased entities. So this check is not required.
Title: Re: Selection by Handle greater than
Post by: qwrtz on April 24, 2015, 05:46:04 PM
Thanks, everyone, for all the replies at lightning speed. I'm amazed that MP and Lee Mac read my post, designed a solution, wrote the code, tested it, and posted it, all in 15 or 20 minutes. I worked on it all day and got nowhere.

I should have clarified in the original post that I didn't want to write a routine that creates specific new entities. I wanted the routine to execute a normal COPY or MIRROR command (with the selection set and displacement or mirror line specified at run time), except that when it's done all the newly created entities are selected for use in the next command.

I was able to do that by calling MP's routine. I still don't understand how that routine works, but it does what I need and it'll be a big help to me. Again, thanks very much.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:mpcopy ()
  2. (setq EntName1 (cdr (assoc -1 (entget (entlast)))))
  3. (setvar "COPYMODE" 1)
  4. (setq ss1 (ssget))
  5. (command "COPY" ss1 "" pause pause)
  6. (setvar "COPYMODE" 0)
  7. (setq ss1 (_ssafter EntName1))
  8. (sssetfirst nil ss1)
  9. )

Code - Auto/Visual Lisp: [Select]
  1. (defun c:mpmirror ()
  2. (setq EntName1 (cdr (assoc -1 (entget (entlast)))))
  3. (princ "Select objects to be mirrored...")
  4. (setq ss1 (ssget) )
  5. (setq s1 (getvar "orthomode") )
  6. (setvar "orthomode" 1)
  7. (setq p1 (getpoint "Start of mirror line...") )
  8. (setq p2 (getpoint p1 "...end of mirror line...") )
  9. (setvar "orthomode" s1)
  10. (initget "Yes No")
  11. (setq s2 (getkword "Delete the original? <N>") )
  12. (if (not s2) (setq s2 "no") )
  13. (command "Mirror" ss1 "" p1 p2 s2 )
  14. (setq ss1 (_ssafter EntName1))
  15. (sssetfirst nil ss1)
  16. )
Title: Re: Selection by Handle greater than
Post by: MP on April 25, 2015, 09:57:55 AM
You're welcome, glad it helped. On the "fast response", I wrote that function 10 or more years ago. Your original post was rather serendipitous as I happened to reference said function not 5 minutes before your inquiry.
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 25, 2015, 10:49:43 AM
You're most welcome qwrtz  :-)

A few points to note:

Since the value of DXF Group -1 is a pointer to the entity itself, observe that:
Code - Auto/Visual Lisp: [Select]
  1. (cdr (assoc -1 (entget (entlast))))

Is equivalent to just:
Code - Auto/Visual Lisp: [Select]



Be careful when stepping through the entities following a call to (entlast) since, if the entity returned by (entlast) is a complex entity (such as an attributed block or 3D polyline), the subsequent calls to (entnext) will return the subentities which follow the parent entity (i.e. the attribute references or 3D polyline vertices respectively). For this reason, I suggested the lastent function that I posted above, which will return the last entity in the drawing database for which a call to (entnext) will return nil.

The same logic applies to MP's _SSAfter function: note that this function will attempt to add subentities to the returned selection set; since it is not possible to add the terminating SEQEND entity to a selection set, the ssadd function will consequently return nil, causing the ss variable to become nil within the while loop, and so the function will always return nil if complex entities have been added to the database after the entity supplied to the function.



I should have clarified in the original post that I didn't want to write a routine that creates specific new entities. I wanted the routine to execute a normal COPY or MIRROR command (with the selection set and displacement or mirror line specified at run time), except that when it's done all the newly created entities are selected for use in the next command.

Perhaps my example was confusing since the example was creating entirely new objects, but please note that the same method may be applied to any command for which you want to obtain the set of all entities potentially created by the command, e.g.:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:lmcopy ( / cpm ent new sel )
  2.    
  3.     (if ;; If the following expression returns a non-nil value
  4.         ;; (i.e. if the user makes a valid selection)
  5.         (setq sel (ssget)) ;; Prompt the user for a selection
  6.         (progn
  7.            
  8.             (setq ent (lastent) ;; Retrieve the last entity added to the database
  9.                   new (ssadd)   ;; Create an empty selection set for the new entities
  10.                   cpm (getvar 'copymode) ;; Store the value of the COPYMODE sys var
  11.             ) ;; end setq
  12.            
  13.             (setvar 'copymode 1)
  14.             ;; Set the COPYMODE sys var as appropriate
  15.            
  16.             (command "_.copy" sel "" "\\" "\\") ;; Invoke the COPY command
  17.            
  18.             (setvar 'copymode cpm)
  19.             ;; Reset the COPYMODE sys var
  20.             ;; (always store/restore the original sys var value, don't assume that you know what that value should be)
  21.            
  22.             (while (setq ent (entnext ent)) ;; While there is another entity in the database
  23.                 (ssadd ent new) ;; Add it to the new selection set
  24.                
  25.                 ;; If subentities follow this entity
  26.                 (if (= 1 (cdr (assoc 66 (entget ent))))
  27.                    
  28.                     ;; Iterate over them until we reach the terminating SEQEND entity:
  29.                     (while (/= "SEQEND" (cdr (assoc 0 (entget ent))))
  30.                         (setq ent (entnext ent))
  31.                     ) ;; end while
  32.                 ) ;; end if
  33.             ) ;; end while
  34.  
  35.             ;; Highlight the new objects
  36.             (sssetfirst nil new)
  37.            
  38.         ) ;; end progn
  39.     ) ;; end if
  40.    
  41.     ;; Supress the return of the last evaluated expression
  42.     (princ)
  43. ) ;; end defun
  44.  
  45. (defun lastent ( / rtn tmp )
  46.     (setq rtn (entlast))
  47.     (while (setq tmp (entnext rtn)) (setq rtn tmp))
  48.     rtn
  49. )
Title: Re: Selection by Handle greater than
Post by: MP on April 25, 2015, 11:48:34 AM
Good eye and commentary regarding attempts to grab seqends. When I wrote that function it was to harvest entities created by flattening processes by reverse engineered dxb files or wmfin exploits (essentially all simple primitives). Revised function to harvest only primary entities. Thanks Lee.
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 25, 2015, 11:59:57 AM
Good eye and commentary regarding attempts to grab seqends. When I wrote that function it was to harvest entities created by flattening processes by reverse engineered dxb files or wmfin exploits (essentially all simple primitives). Revised function to harvest only primary entities. Thanks Lee.

No worries - of course, there is no need for superfluous error checking if it doesn't befit the task  :-)

I like the clean solution to excluding subentities - perhaps ATTRIB should be added to the list?

Lee
Title: Re: Selection by Handle greater than
Post by: MP on April 25, 2015, 12:12:21 PM
Yep, attribs should be there, was in my brain when I started to do the mod, I blame my distracting cat, lol.
Title: Re: Selection by Handle greater than
Post by: qwrtz on April 25, 2015, 05:38:22 PM
Lee Mac, thanks so much for the revised function, which does exactly what I want, and especially for the remarks included with it.

I tried to adapt it to make an equivalent Mirror command, but this always terminates with nothing selected. What did I do wrong?

Code - Auto/Visual Lisp: [Select]
  1. (defun c:lmMirror ( / otm ent new sel )
  2.  
  3.     (if ;; If the following expression returns a non-nil value
  4.         ;; (i.e. if the user makes a valid selection)
  5.         (setq sel (ssget)) ;; Prompt the user for a selection
  6.         (progn
  7.  
  8.             (setq ent (lastent) ;; Retrieve the last entity added to the database
  9.                   new (ssadd)   ;; Create an empty selection set for the new entities
  10.                   otm (getvar 'orthomode) ;; Store the value of the ORTHOMODE sys var
  11.             ) ;; end setq
  12.  
  13.             (setvar 'orthomode 1)
  14.             ;; Set the ORTHOMODE sys var as appropriate
  15.  
  16.             (command "_.mirror" sel "" "\\" "\\") ;; Invoke the MIRROR command
  17.  
  18.             (setvar 'orthomode otm)
  19.             ;; Reset the ORTHOMODE sys var
  20.             ;; (always store/restore the original sys var value, don't assume that you know what that value should be)
  21.  
  22.             (while (setq ent (entnext ent)) ;; While there is another entity in the database
  23.                 (ssadd ent new) ;; Add it to the new selection set
  24.  
  25.                 ;; If subentities follow this entity
  26.                 (if (= 1 (cdr (assoc 66 (entget ent))))
  27.  
  28.                     ;; Iterate over them until we reach the terminating SEQEND entity:
  29.                     (while (/= "SEQEND" (cdr (assoc 0 (entget ent))))
  30.                         (setq ent (entnext ent))
  31.                     ) ;; end while
  32.                 ) ;; end if
  33.             ) ;; end while
  34.  
  35.             ;; Highlight the new objects
  36.             (sssetfirst nil new)
  37.  
  38.         ) ;; end progn
  39.     ) ;; end if
  40.  
  41.     ;; Supress the return of the last evaluated expression
  42.     (princ)
  43. ) ;; end defun
  44.  

And I hate to be greedy, but there are a couple of things I still don't understand:

1.
....if the entity returned by (entlast) is a complex entity (such as an attributed block or 3D polyline), the subsequent calls to (entnext) will return the subentities which follow the parent entity (i.e. the attribute references or 3D polyline vertices respectively). For this reason, I suggested the lastent function that I posted above, which will return the last entity in the drawing database for which a call to (entnext) will return nil.
Does that mean that (lastent) returns the last non-complex entity? If so, what if there's a newer entity that is complex? What keeps that newer complex entity from being included in the final selection set? I see where you skip over the sub-entities, but where do you skip over a complex entity that's newer than the last non-complex entity?

2. What's that rtn all by itself at the end of the (lastent) function) It's not part of any expression other than the (defun) function, so I'm surprised it's even allowed in (defun sym ([arguments] [/ variables ...]) expr ...). And what does it do?
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 25, 2015, 06:05:22 PM
Lee Mac, thanks so much for the revised function, which does exactly what I want, and especially for the remarks included with it.

Excellent - you're welcome  :-)

I tried to adapt it to make an equivalent Mirror command, but this always terminates with nothing selected. What did I do wrong?

Note that the MIRROR command has an additional prompt (Erase source objects? [Yes/No] <N>:), hence an additional pause or automated input is required:
Code - Auto/Visual Lisp: [Select]
  1. (command "_.mirror" sel "" "\\" "\\" "")

And I hate to be greedy, but there are a couple of things I still don't understand:

Don't worry - ask away! Sharing knowledge is what this place is all about  :-)

1.
....if the entity returned by (entlast) is a complex entity (such as an attributed block or 3D polyline), the subsequent calls to (entnext) will return the subentities which follow the parent entity (i.e. the attribute references or 3D polyline vertices respectively). For this reason, I suggested the lastent function that I posted above, which will return the last entity in the drawing database for which a call to (entnext) will return nil.
Does that mean that (lastent) returns the last non-complex entity? If so, what if there's a newer entity that is complex? What keeps that newer complex entity from being included in the final selection set? I see where you skip over the sub-entities, but where do you skip over a complex entity that's newer than the last non-complex entity?

Not quite -

(entlast) will return the last visible primary entity in the database, however, in the case of a complex entity such as an attributed block reference or 3D polyline, there will be subentities (attribute references / vertices) which follow the primary entity in the database.

Therefore, if the last object added to the database was complex and we were to step through the database starting from the entity returned by (entlast), we would encounter the subentities which belong to that complex entity before encountering the new objects created by the command(s) invoked following the call to (entlast).

Whereas, my (lastent) function will obtain the last visible primary entity using a call to (entlast) and will then continue to iterate over the drawing database from this entity until there are no further subentities (i.e. when (entnext) returns nil), at which point the function will return the entity occupying the very last index in the database. Of course, if the initial call to (entlast) returns a non-complex entity (such as a LINE, POINT etc.), the call to (entnext) will immediately return nil (as there are no subentities which follow), and the primary entity will be returned by the function as if (entlast) had been used.

2. What's that rtn all by itself at the end of the (lastent) function) It's not part of any expression other than the (defun) function, so I'm surprised it's even allowed in (defun sym ([arguments] [/ variables ...]) expr ...). And what does it do?

When evaluated, a function will return the last evaluated expression within the defun expression; in this case, the last evaluated expression is the symbol 'rtn' which is evaluated to yield the value to which it points - that is, the last entity in the database.

Consider that if the isolated 'rtn' symbol were not present at the end of the function, the function would instead return the value returned by the while expression; and since while returns the value of the last evaluated expression following the test expression, the lastent function would return nil if the entity returned by the initial (entlast) call was non-complex (as the test expression for the while loop would immediately return nil).
Title: Re: Selection by Handle greater than
Post by: qwrtz on April 25, 2015, 06:55:49 PM
Understood! Thanks again.

I left out the third input to the Mirror command because I wanted to be able to specify yes or no at run time. I didn't realize that would mess up the building of the new selection set. I guess I have to prompt for the two clicks and the yes or no and then pass all the input to the Mirror command.

But with the following code, answering Yes suppresses the creation of a new selection set. I only get a selection set on termination if I answer N or Enter. Can you see what I did wrong?

Code - Auto/Visual Lisp: [Select]
  1. (defun c:lmMirror ( / otm ent new sel )
  2.  
  3.     (if ;; If the following expression returns a non-nil value
  4.         ;; (i.e. if the user makes a valid selection)
  5.         (setq sel (ssget)) ;; Prompt the user for a selection
  6.  
  7.         (progn
  8.  
  9.             (setq ent (lastent) ;; Retrieve the last entity added to the database
  10.                   new (ssadd)   ;; Create an empty selection set for the new entities
  11.                   otm (getvar 'orthomode) ;; Store the value of the ORTHOMODE sys var
  12.             ) ;; end setq
  13.  
  14.             (setvar 'orthomode 1)
  15.             ;; Set the ORTHOMODE sys var as appropriate
  16.                        
  17.             (setq p1 (getpoint "First point of mirror line: ")
  18.                   p2 (getpoint p1 "Second point: ")
  19.              )
  20.                        
  21.             (initget "Yes No")
  22.             (setq yn (getkword "Delete the original? <N>") )
  23.             (if (not yn) (setq yn "no") )
  24.  
  25.             (command "_.mirror" sel "" p1 p2 yn) ;; Invoke the MIRROR command
  26.             (setvar 'orthomode otm)
  27.             ;; Reset the ORTHOMODE sys var
  28.             ;; (always store/restore the original sys var value, don't assume that you know what that value should be)
  29.  
  30.             (while (setq ent (entnext ent)) ;; While there is another entity in the database
  31.                 (ssadd ent new) ;; Add it to the new selection set
  32.  
  33.                 ;; If subentities follow this entity
  34.                 (if (= 1 (cdr (assoc 66 (entget ent))))
  35.  
  36.                     ;; Iterate over them until we reach the terminating SEQEND entity:
  37.                     (while (/= "SEQEND" (cdr (assoc 0 (entget ent))))
  38.                         (setq ent (entnext ent))
  39.                     ) ;; end while
  40.                 ) ;; end if
  41.             ) ;; end while
  42.  
  43.             ;; Highlight the new objects
  44.             (sssetfirst nil new)
  45.  
  46.         ) ;; end progn
  47.     ) ;; end if
  48.  
  49.     ;; Supress the return of the last evaluated expression
  50.     (princ)
  51. ) ;; end defun
  52.  
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 26, 2015, 07:17:35 AM
I left out the third input to the Mirror command because I wanted to be able to specify yes or no at run time. I didn't realize that would mess up the building of the new selection set. I guess I have to prompt for the two clicks and the yes or no and then pass all the input to the Mirror command.

Not necessarily - I used the empty string "" (which represents the user pressing Enter) to accept the default option at this prompt, however, you could use another pause ("\\") to pause for user input at the prompt, as used with the point prompts.

But with the following code, answering Yes suppresses the creation of a new selection set. I only get a selection set on termination if I answer N or Enter. Can you see what I did wrong?

I wouldn't say that you've done anything wrong - the issue is that the MIRROR command behaves differently when the user opts to delete the original objects (this is one reason why I tend to avoid using AutoCAD commands in my code, as you become reliant on the behaviour of the command under each condition).

When the user opts to delete the original objects, the mirror transformation is applied to the original entities, rather than to copies of the original entities; therefore, to account for this, I would suggest the following:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:lmMirror ( / otm ent flg new pt1 pt2 sel )
  2.  
  3.     (if ;; If the following expression returns a non-nil value
  4.         ;; (i.e. if the user makes a valid selection)
  5.         (and
  6.             (setq sel (ssget)) ;; Prompt the user for a selection
  7.             (setq pt1 (getpoint "\nSpecify first point of mirror line: ")) ;; Prompt for first point
  8.             (setq pt2 (getpoint "\nSpecify second point of mirror line: " pt1)) ;; Prompt for second point
  9.         )
  10.         (progn
  11.  
  12.             (setq ent (lastent) ;; Retrieve the last entity added to the database
  13.                   new (ssadd)   ;; Create an empty selection set for the new entities
  14.                   otm (getvar 'orthomode) ;; Store the value of the ORTHOMODE sys var
  15.             ) ;; end setq
  16.  
  17.             (setvar 'orthomode 1)
  18.             ;; Set the ORTHOMODE sys var as appropriate
  19.  
  20.             ;; Issue the final MIRROR command prompt separately in order to collect the chosen option
  21.             (initget "Yes No")
  22.             (setq flg (cond ((getkword "\nErase source objects? [Yes/No] <N>: ")) ("No")))
  23.  
  24.             (command "_.mirror" sel "" "_non" pt1 "_non" pt2 flg) ;; Invoke the MIRROR command
  25.  
  26.             (setvar 'orthomode otm)
  27.             ;; Reset the ORTHOMODE sys var
  28.             ;; (always store/restore the original sys var value, don't assume that you know what that value should be)
  29.  
  30.             ;; If the mirror transformation was applied to the original objects
  31.             (if (= "Yes" flg)
  32.                 ;; Highlight the original selection
  33.                 (setq new sel)
  34.                 ;; Else collect the new objects
  35.                 (while (setq ent (entnext ent)) ;; While there is another entity in the database
  36.                     (ssadd ent new) ;; Add it to the new selection set
  37.      
  38.                     ;; If subentities follow this entity
  39.                     (if (= 1 (cdr (assoc 66 (entget ent))))
  40.      
  41.                         ;; Iterate over them until we reach the terminating SEQEND entity:
  42.                         (while (/= "SEQEND" (cdr (assoc 0 (entget ent))))
  43.                             (setq ent (entnext ent))
  44.                         ) ;; end while
  45.                     ) ;; end if
  46.                 ) ;; end while
  47.             ) ;; end if
  48.  
  49.             ;; Highlight the new objects
  50.             (sssetfirst nil new)
  51.  
  52.         ) ;; end progn
  53.     ) ;; end if
  54.  
  55.     ;; Supress the return of the last evaluated expression
  56.     (princ)
  57. ) ;; end defun
  58.  
  59. (defun lastent ( / rtn tmp )
  60.     (setq rtn (entlast))
  61.     (while (setq tmp (entnext rtn)) (setq rtn tmp))
  62.     rtn
  63. )
Title: Re: Selection by Handle greater than
Post by: qwrtz on April 27, 2015, 09:36:21 AM
Yes, that works. I should have realized the old objects were just being moved and re-oriented. Thanks for fixing that.

.... I tend to avoid using AutoCAD commands in my code, as you become reliant on the behaviour of the command under each condition.

Great idea. Then you don't have to revise them each time Autodesk makes a change to the input that a command expects. I should have done that. I've got custom versions of nearly every command I use, but I wrote them all using the (command) function and so I dread each new version and what it's going to do to my custom commands. Maybe I should start re-writing them.

I've been re-reading the earlier discussion between you and MP and I have a question about that:  It sounds like the only problem with MP's (_ssAfter) function is that it might try to add a SEQEND to a selection set, and that would fail and the function would return nil. If that's the only problem, wouldn't it be easy to protect against that possibility by checking to see (if (/= "SEQEND" (cdr (assoc 0 (entget e))))) before adding each entity?
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 27, 2015, 05:47:15 PM
I've been re-reading the earlier discussion between you and MP and I have a question about that:  It sounds like the only problem with MP's (_ssAfter) function is that it might try to add a SEQEND to a selection set, and that would fail and the function would return nil. If that's the only problem, wouldn't it be easy to protect against that possibility by checking to see (if (/= "SEQEND" (cdr (assoc 0 (entget e))))) before adding each entity?

Indeed - that is pretty much the modification that MP has implemented following my earlier comments; except that you also want to exclude the subentities which follow a complex entity since, although such entities can be added to a selection set, they cannot be processed by a command or selected & gripped and so it is pointless to include them.

It sounds like you now have a good grasp of these concepts, well done.

Lee
Title: Re: Selection by Handle greater than
Post by: qwrtz on April 27, 2015, 09:03:28 PM
I was thinking the same thing myself. I'm amazed at how much more I know about this subject and about Autolisp in general than I did just a week ago. Good instruction!
Title: Re: Selection by Handle greater than
Post by: Lee Mac on April 28, 2015, 06:20:57 AM
Thank you - that's great to hear!  :-)