Author Topic: Minimum Clicks with ssget  (Read 13860 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #15 on: September 12, 2004, 08:15:01 PM »
Thanks Stig.
I'll try it out in the am...
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #16 on: September 13, 2004, 10:45:03 AM »
Here's a slightly extended version. Type L for Last or S for something else ;)

Code: [Select]
(defun picktext (/ ent pt2 resp ss)
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (if (and (<= (length ent) 2)
             (member (cdr (assoc 0 (entget (car ent))))
                     '("TEXT" "MTEXT")
             )
        )
      (car ent)
    )
  )
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst (list "TEXT" "MTEXT"))))
      )
    ;;  no set so get user input
    (while resp
      ;; prompt user
      (prompt "\nSelect object(s): ")
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3)
         ;; go look for entity at clicked point
         (cond
           ((setq ent (nentselp (cadr resp)))
            ;; got a text ent? save it and exit loop
            (and (setq ent (chkpick ent)) (setq resp nil))
           )
           ;; otherwise, make a window selection and see what you got
           ((setq pt2 (getcorner (cadr resp)))
                                        ; user to pick window corner
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget "_W" (cadr resp) pt2
                                 '((0 . "TEXT,MTEXT"))))
                 (setq resp nil)
            )
           )
         )
        )
        ;; user hit space or return?
        ((= (car resp) 2)
         (and (member (cadr resp) '(13 32)) (setq resp nil))
         ;; user hit L/l for Last?
         (and (member (cadr resp) '(76 108))
              (setq ent (chkpick (list (entlast))))
              (setq resp nil)
         )
         (and (member (cadr resp) '(83 115))
              (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                       115 32 119 101 105 114 100))))
        )
      )
    )
  )
  ;; return entity or selection set
  (cond (ent)(ss))
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #17 on: September 13, 2004, 11:11:34 AM »
Stig you're very clever. 8)
You got the pick box using grread.

Nice touch with L but S had me LOL.


I think this routine is a keeper.

Perhaps calling picktext with a list of types would make the routine more
universal.  ( picktext ( list "TEXT" "MTEXT"))
And it might need the prompt passed to it as well ( picktext types prmpt )

All in all a very good job. I like it. :D
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #18 on: September 13, 2004, 11:54:09 AM »
Quote from: CAB
Nice touch with L but S had me LOL.

Not quite in compliance with standard GUI but what the heck  heh

Quote from: CAB
Perhaps calling picktext with a list of types would make the routine more universal.  ( picktext ( list "TEXT" "MTEXT"))
And it might need the prompt passed to it as well ( picktext types prmpt )

Excellent idea.

Thanks for the comments.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #19 on: September 13, 2004, 01:07:15 PM »
Stig,
Here is what I got so far but got stuck on the rephrasing of
 ( "TEXT" "MTEXT")   to ( 0 . "TEXT,MTEXT")

And what to do if the user wants ALL types of objects. ? nil filter

Updated with Stigs code..

Code: [Select]
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   lst -> a list of object types like ("TEXT" "MTEXT")  
;;;
;;; USAGE
;;;   (setq ss (getpickfirst typs))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 S. Madsen
;;; http://www.smadsen.com/
;;;
;;; VERSION
;;; 1.0 Sep. 13, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun getpickfirst (lst / ss a ent)
  ;;  lst is a list of object types like ("TEXT" "MTEXT")
  (cond ((setq ss (cadr (ssgetfirst))) ; get previously selected sel set
         (setq a 0) ; set pointer
         (repeat (sslength ss) ; foreach object in sel set
           (setq ent (ssname ss a) ; get obj name
                 a   (1+ a)
           ) ; increment counter
           ;; is obj not a member of the list ?
           (and (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss) ; if not a member remove it from ss
                (setq a (1- a)) ; and deincrement pointer
           ) ; and
         ) ; repeat
        ) ; end cons 1
  ) ; end cond stmt
  ;; if ss is a pick set and has objects then return the selection set
  (if (and (= (type ss) 'pickset) (/= 0 (sslength ss)))
    ss
  )
  ;;  else return nil because when IF fails it returns nil
) ; end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   typs is a list of exceptable onject types
;;;   prmpt is the prompt string to use for user select
;;;
;;; USAGE
;;;  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect object(s): "))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 S. Madsen
;;; http://www.smadsen.com/
;;;
;;; VERSION
;;; 1.0 Sep. 13, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun picktext ( typs prmpt / ent pt2 resp ss)
  ;;  typs is a list of exceptable onject types
  ;;  prmpt is the prompt string to use for user select
 
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (if (and (<= (length ent) 2)
             (member (cdr (assoc 0 (entget (car ent)))) typs)
        )
      (car ent)
    )
  )

  ;;  phrase the typs list from ("TEXT" "MTEXT")
  ;;  to (0 . "TEXT,MTEXT")
  (defun sstypes (lst / str)
    (cond ((not lst) (cons 0 "*"))
          ((setq str "")
           (foreach n lst
             (setq str (strcat n "," str))
           )
           (cons 0 str)
          )
    )
  )
 
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst typs)))
      )
    ;;  no set so get user input
    (while resp
      ;; prompt user
      (prompt prmpt)
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3) ; Selected point
         ;; go look for entity at clicked point
         (cond
           ((setq ent (nentselp (cadr resp)))
            ;; got a text ent? save it and exit loop
            (and (setq ent (chkpick ent)) (setq resp nil))
           ) ; end cond 1
           ;; otherwise, make a window selection and see what you got
           ((and (null (initget 32)); dash line in rectangle
                 (setq pt2 (getcorner (cadr resp))); user pick window corner
            )
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget "_W" (cadr resp) pt2 (sstypes typs)))
                 (setq resp nil)  ; exit loop
            )
           ) ; end cond 2
         ); end cond stmt
         (if resp
           (prompt "\n*-*  Error, wrong object type.  Try again.  *-*")
         )
        ) ; end cond 1
       
        ((= (car resp) 2); Keyboard input
         ;; user hit space or return?
         (and (member (cadr resp) '(13 32))
              (setq resp nil) ; exit loop
         )
         ;; user hit L/l for Last?
         (and (member (cadr resp) '(76 108))
              (setq ent (chkpick (list (entlast))))
              (setq resp nil) ; exit loop
         )
         ;; user hit S/s for Stig?
         (and (member (cadr resp) '(83 115))
              (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                       115 32 119 101 105 114 100))))
        ) ; end cond 2
      ); end cond stmt
    ); while
  ); endif
  ;; return entity or selection set
  (cond (ent)(ss))
); end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;;  Sample call to the function
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun c:test(/ ss)
  ;; Get only text or mtext objects
  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect TEXT object(s): "))
  (cond
    ((null ss)
      (prompt "\n*-*  Nothing selected.  *-*")
    )
    ((= (type ss) 'ENAME)
      (prompt "\n*-*  Single object selected.  *-*")
    )
    ((prompt "\n*-*  Selection set created.  *-*"))
  )
  (princ)
)
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;EOF
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #20 on: September 13, 2004, 02:24:46 PM »
Maybe something like this?

Code: [Select]
(defun sstypes (lst / str)
  (cond ((not lst) (cons 0 "*"))
        ((setq str "")
         (foreach n lst
           (setq str (strcat n "," str))
         )
         (cons 0 str)
        )
  )
)


(sstypes '("TEXT" "MTEXT"))
(0 . "MTEXT,TEXT,")

(sstypes nil)
(0 . "*")

The extra comma doesn't interfere.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #21 on: September 13, 2004, 02:40:18 PM »
Ok, good, I added it to the code above. :)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #22 on: September 13, 2004, 06:59:29 PM »
I updated the code above to the latest version.

I changes the ssget "_W" to "_C"  in an attempt to allow picking from
right to left to be crossing and left to right to be window. This should
work but it doesn't. It is crossing no matter what. I am using ACAD2000
for the testing. I suppose I could test pick points to see if they are
left to right & use "_W" , else use "_C".

Your thought?

Couldn't wait, I changed it 8)

Revised Code 09/14/2004
Code: [Select]

;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   lst -> a list of object types like ("TEXT" "MTEXT")  
;;;
;;; USAGE
;;;   (setq ss (getpickfirst typs))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler  
;;;          Co-author S. Madsen
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;; 1.0 Sep. 14, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun getpickfirst (lst / ss a ent)
  ;;  lst is a list of object types like ("TEXT" "MTEXT")
  (cond ((setq ss (cadr (ssgetfirst))) ; get previously selected sel set
         (setq a 0) ; set pointer
         (repeat (sslength ss) ; foreach object in sel set
           (setq ent (ssname ss a) ; get obj name
                 a   (1+ a)
           ) ; increment counter
           ;; is obj not a member of the list ?
           (and (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss) ; if not a member remove it from ss
                (setq a (1- a)) ; and deincrement pointer
           ) ; and
         ) ; repeat
        ) ; end cons 1
  ) ; end cond stmt
  ;; if ss is a pick set and has objects then return the selection set
  (if (and (= (type ss) 'pickset) (/= 0 (sslength ss)))
    ss
  )
  ;;  else return nil because when IF fails it returns nil
) ; end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   typs is a list of exceptable object types, nil = all types
;;;   prmpt is the prompt string to use for user select
;;;     nil = "Select object(s): "
;;;
;;; USAGE
;;;  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect object(s): "))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler  
;;;          Co-author S. Madsen
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;; 1.0 Sep. 14, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun picktext ( typs prmpt / ent pt2 resp ss wtype)
  ;;  typs is a list of exceptable onject types
  ;;  prmpt is the prompt string to use for user select
 
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (cond
      ((null typs)
       (car ent)
      )
      ((and (<= (length ent) 2)
            (member (cdr (assoc 0 (entget (car ent)))) typs)
        )
        (car ent)
       )
    )
  )
 
  ;;  phrase the typs list from ("TEXT" "MTEXT")
  ;;  to (0 . "TEXT,MTEXT")
  (defun sstypes (lst / str)
    (cond ((not lst) (cons 0 "*"))
          ((setq str "")
           (foreach n lst
             (setq str (strcat n "," str))
           )
           (cons 0 str)
          )
    )
  )
 
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst typs)))
      )
    ;;  no set so get user input
    (while resp
      (if prmpt ; prompt user
        (prompt prmpt)
        (prompt "\nSelect object(s): ")
      )
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3) ; Selected point
         ;; go look for entity at clicked point
         (cond
           ((setq ent (nentselp (cadr resp)))
            ;; got a text ent? save it and exit loop
            (and (setq ent (chkpick ent)) (setq resp nil))
           ) ; end cond 1
           ;; otherwise, make a window selection and see what you got
           ((and (null (initget 32)); dash line in rectangle
                 (setq pt2 (getcorner (cadr resp))); user pick window corner
            )
            (if (< (caadr resp)(car pt2))
              (setq wtype "_W"); picked left to right
              (setq wtype "_C"); picked right to left
            )
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget wtype (cadr resp) pt2 (list(sstypes typs))))
                 (setq resp nil)  ; exit loop
            )
           ) ; end cond 2
         ); end cond stmt
         (if resp
           (prompt "\n*-*  Error, wrong object type.  Try again.  *-*")
         )
        ) ; end cond 1
       
        ((= (car resp) 2); Keyboard input
          (cond
            ;; user hit space or return?
            (and (member (cadr resp) '(13 32))
                 (setq resp nil) ; exit loop
            ) ; end cond 1
            ;; user hit L/l for Last?
            (and (member (cadr resp) '(76 108))
                 (setq ent (chkpick (list (entlast))))
                 (setq resp nil) ; exit loop
            ) ; end cond 2
            ;; user hit S/s for Stig?
            (and (member (cadr resp) '(83 115))
                 (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                          115 32 119 101 105 114 100)))
            ) ; end cond 3
          ); end cond stmt
        ) ; end cond 2
      ); end cond stmt
    ); while
  ); endif

  ;;========================================
  ;;  Return entity or selection set or nil
  (cond
    (ent)
    ((null ss) nil)
    ((=(sslength ss)1)(ssname ss 0))
    (ss)
  )
  ;;========================================
); end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;;  Sample call to the function
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun c:test(/ ss)
  ;; Get only text or mtext objects
  ;(setq ss (picktext nil nil))
  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect TEXT object(s): "))
  (cond
    ((null ss)
      (prompt "\n*-*  Nothing selected.  *-*")
    )
    ((= (type ss) 'ENAME)
      (prompt "\n*-*  Single object selected.  *-*")
    )
    ((prompt (strcat "\n*-*  Selection set created with "
                     (itoa (sslength ss)) " objects.   *-*")))
  )
  (princ)
)
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;EOF
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #23 on: September 14, 2004, 09:07:03 AM »
Quote from: CAB
Your thought?

Ummm, my thought is that the W/C selection is perhaps not as obvious as it could be? I know it requires a different construct to visibly show the difference so maybe it should go for one selection method only, which could then be specified as an argument? I dunno.

In the last condition you need to check for selection set before trying to get the SSLENGTH, e.g.

(cond (ent) (ss (if (=(sslength ss)1)(ssname ss 0) ss)))


I know it's my fault but the key search conditions should be wrapped in a COND as not to run through all conditions:

Code: [Select]
....
        ((= (car resp) 2); Keyboard input
         ;; user hit space or return?
         (cond ((member (cadr resp) '(13 32))
                (setq resp nil)         ; exit loop
               )
               ;; user hit L/l for Last?
               ((and (member (cadr resp) '(76 108))
                     (setq ent (chkpick (list (entlast)))))
                (setq resp nil)         ; exit loop
               )
               ;; user hit S/s for Stig?
               ((member (cadr resp) '(83 115))
                (princ (vl-list->string
                         '(10 83 101 55 101 110 32 105 115 32 119 101
                           105 114 100)))
               )
         ) ; end cond 2
   ....


Heh I appreciate the S option still being in it

Btw, you should copyright it in your own name. Feel free to leave my name in it but only as a co-author without reserved rights in any form.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #24 on: September 14, 2004, 10:17:02 AM »
Quote from: Stig
Ummm, my thought is that the W/C selection is perhaps not as obvious as it could
be? I know it requires a different construct to visibly show the difference so
maybe it should go for one selection method only, which could then be specified
as an argument? I dunno.

Perhaps it appeals to me because it's what I am used to. I always have 'Implied Windowing'
On. The left to right being 'Window' and the right to left being 'Crossing Window'.

Quote from: Stig
In the last condition you need to check for selection set before trying to get the SSLENGTH, e.g.

I could not find any case where ss would not be a selection set


Quote from: Stig
the key search conditions should be wrapped in a COND as not to run through all conditions:

Done

Quote from: Stig
Heh I appreciate the S option still being in it

We have to have a little humor from time to time.

Quote from: Stig
Btw, you should copyright it in your own name. Feel free to leave my name in it
 but only as a co-author without reserved rights in any form.
As you wish. Thanks
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #25 on: September 14, 2004, 10:27:28 AM »
Quote from: CAB
Perhaps it appeals to me because it's what I am used to. I always have 'Implied Windowing'
On. The left to right being 'Window' and the right to left being 'Crossing Window'.

Yes but there's a visual aid when using implied windowing, dash/no dash, which would be harder to implement from scratch.

Quote from: Stig
I could not find any case where ss would not be a selection set

If you exit with no pick or selection it returns nil. SSLENGHT doesn't like nil :)

JohnK

  • Administrator
  • Seagull
  • Posts: 10644
Minimum Clicks with ssget
« Reply #26 on: September 14, 2004, 10:48:13 AM »
Very nice sofar guys! Are you guys using the CVS for this lil progy? (Could be our very first ones to use the CVS for code development.)
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #27 on: September 14, 2004, 10:51:08 AM »
Code development? What's that?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #28 on: September 14, 2004, 10:55:12 AM »
Quote from: SMadsen
Yes but there's a visual aid when using implied windowing, dash/no dash, which would be harder to implement from scratch.

Well, would you believe I never paid any attention to it. I guess I need to open my eyes. :shock:

Quote from: SMadsen
If you exit with no pick or selection it returns nil. SSLENGHT doesn't like nil :)


How about this?
Code: [Select]
(cond (ent) ((null ss) nil) ((=(sslength ss)1)(ssname ss 0)) (ss))
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #29 on: September 14, 2004, 10:57:22 AM »
Quote from: Se7en
Very nice sofar guys! Are you guys using the CVS for this lil progy? (Could be our very first ones to use the CVS for code development.)


Ooops, I think we are done  :roll:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.