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

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« on: September 11, 2004, 03:07:53 PM »
Trying to create a routine to do the following:

Get a TEXT object,
  If not a text object use the point picked as the first corner
  of a selection box to get a selection set of text objects.
 
problem using entsel is that if nul a point is not returned
 
This is how I solved the problem but was wondering if someone had a
better or differant solution.
Code: [Select]
(defun c:test (/ ent pt pt2 idx ss)
  (while ; loop until point is picked
    (not
      (setq
        pt (getpoint "\nSelect Text to Increment or select a group of text.")
      )
    )
     (princ "\nPlease try again...")
  )

  (cond
    ;;=================================================
    ((setq ss (ssget pt '((0 . "TEXT,MTEXT"))))
     ;; user picked a text object
     (setq ent (ssname ss 0))
     (if (cdr (assoc 3 (entget ent)))
       (prompt "\nMTEXT is too large, not supported!")
       (prompt "\nGot a single text object.")
     ) ; endif
    ) ; end cond 1

    ;;=================================================
    ;; No text selected so get a selection set
    ((and (setq pt2 (getcorner pt)) ; user to pick window corner
          (setq ss (ssget "_C" pt pt2 '((0 . "TEXT,MTEXT"))))
     )
     (setq idx (sslength ss)) ; got some text objects
     (while (>= (setq idx (1- idx)) 0)
       (setq ent (ssname ss idx))
       (if (cdr (assoc 3 (entget ent)))
         (prompt "\nMTEXT is too large, not supported!")
         (prompt "\nGot a sel set of text objects.")
       ) ; endif
     ) ; end while
    ) ; end cond 2

    ((prompt "\n*-*  Not Text, Try again. *-*")
    ) ; end cond 3
  ) ; end cond stmt
  (princ)
)

If you use
Code: [Select]
(cond
  ((setq ss (ssget ":S" '((0 . "TEXT,MTEXT")))))
  ((setq ss (ssget '((0 . "TEXT,MTEXT")))))
)

The user has to click twice to start the second ssget
If you use
Code: [Select]
((setq ss (ssget '((0 . "TEXT,MTEXT")))))
you have to click twice to get a single text object.

Any ideas?
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.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Minimum Clicks with ssget
« Reply #1 on: September 12, 2004, 12:06:03 AM »
Actually it looks like a viable solution to me
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #2 on: September 12, 2004, 09:25:31 AM »
Thanks Keith,
I was hoping there was some vlax magic that would give you the point
data from a entsel when it missed an object.
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 #3 on: September 12, 2004, 10:10:31 AM »
I agree with Keith.

To get a pickbox cursor, you could use the SSGET ":E" method but it probably needs additional handling.

I noticed you're using a crossing for an empty pick but GETCORNER acts as a window method. Calling INITGET with 32 can give you the dashed appearance that crossing uses.
Another enhancement could be to handle pickfirst selections.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #4 on: September 12, 2004, 11:24:28 AM »
Thanks Stig for the comments.
The _C was a cut & paste error, I'm such a slow typest & do a lot of Cut & paste.
Thanks for the initget 32 tip.
And by 'Pick First' you are refering to the ssget pt where it may pick up more
than one if text is overlapping? If so I added ( and ( = (sslength ss) 1))
to handle that.


Code: [Select]
(defun c:test (/ ent pt pt2 idx ss)
  (while ; loop until point is picked
    (not
      (setq
        pt (getpoint "\nSelect Text to Increment or select a group of text.")))
     (princ "\nPlease try again...")
  )

  (cond
    ;;=================================================
    ((and (setq ss (ssget pt '((0 . "TEXT,MTEXT"))))
          (= (sslength ss) 1)); if >1 force user to get a set
     ;; user picked a text object
     (setq ent (ssname ss 0))
     (if (cdr (assoc 3 (entget ent)))
       (prompt "\nMTEXT is too large, not supported!")
       (prompt "\nGot a single text object.")
     ) ; endif
    ) ; end cond 1

    ;;=================================================
    ;; No text selected so get a selection set
    ((and (null (initget 32))
          (setq pt2 (getcorner pt)) ; user to pick window corner
          (setq ss (ssget "_W" pt pt2 '((0 . "TEXT,MTEXT"))))
     )
     (setq idx (sslength ss)) ; got some text objects
     (while (>= (setq idx (1- idx)) 0)
       (setq ent (ssname ss idx))
       (if (cdr (assoc 3 (entget ent)))
         (prompt "\nMTEXT is too large, not supported!")
         (prompt "\nGot a sel set of text objects.")
       ) ; endif
     ) ; end while
    ) ; end cond 2

    ((prompt "\n*-*  Not Text, Try again. *-*")
    ) ; end cond 3
  ) ; end cond stmt
  (princ)
)
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.

Crank

  • Water Moccasin
  • Posts: 1503
Minimum Clicks with ssget
« Reply #5 on: September 12, 2004, 11:25:44 AM »
I also would expect the pickbox cursor.

Isn't it easier to make a selection and filter the text objects?
Vault Professional 2023     +     AEC Collection

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #6 on: September 12, 2004, 11:34:03 AM »
CAB, with pickfirst I mean gripped entities as returned by SSGETFIRST.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #7 on: September 12, 2004, 11:43:46 AM »
Quote from: SMadsen
CAB, with pickfirst I mean gripped entities as returned by SSGETFIRST.


Wow..
That went right over my head :shock:
I don't see how ssgetfirst applies.

Are you talking about the user seleting a set or object before starting the routine?
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 #8 on: September 12, 2004, 11:49:52 AM »
Quote from: Crack
I also would expect the pickbox cursor.

Isn't it easier to make a selection and filter the text objects?

Crank

The intent of the routine was to have it in a loop so the user could either
pick each text item in the order they wanted OR to select the group of text.
I was trying to eliminate the need for the second click, that is if the user
in making the first pick, picked a non-text object or picked nothing that the
point they picked would be used as the first point in the window to get the
selection set.

Perhaps I was trying to be too fancy.
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 #9 on: September 12, 2004, 12:18:35 PM »
Quote from: CAB
Are you talking about the user seleting a set or object before starting the routine?

Yes, but it was only a suggestion for enhancement, is all. You know, chit-chat   :D

Just cooked this up as a possible filter for a pickfirst set:

Code: [Select]
(defun getpickfirst (lst / ss a ent)
  (cond ((setq ss (cadr (ssgetfirst)))
         (setq a 0)
         (repeat (sslength ss)
           (and (setq ent (ssname ss a)
                      a   (1+ a))
                (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss)(setq a (1- a))
           )
         )
        )
  )
  (if (and (= (type ss) 'PICKSET)(/= 0 (sslength ss))) ss)
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #10 on: September 12, 2004, 01:16:28 PM »
Quote from: SMadsen
Yes, but it was only a suggestion for enhancement, is all. You know, chit-chat   :D

Ok,
I think i understand your lisp :) , I commented it & moved the AND.

this routine would allow the user to select a set prior to starting
the lisp that would then exclude any object type not in your list.

Code: [Select]
;;   Pourpose:
;;   To filter a preselected selection set for object types
;;   listed in the variable list lst
(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


Test call:
Code: [Select]
(defun c:test(/ ss)
  (setq ss (getpickfirst (list "TEXT" "MTEXT")))
  (princ)
)


Very nice, Thanks CAB
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 #11 on: September 12, 2004, 01:34:11 PM »
Here is the revised routine

Code: [Select]
(defun c:test (/ ent pt pt2 idx ss got_ss)
  ;; function to process the selection set
  (defun got_ss (ss / idx ent)
    (setq idx (sslength ss)) ; got some text objects
    (while (>= (setq idx (1- idx)) 0)
      (setq ent (ssname ss idx))
      (if (cdr (assoc 3 (entget ent)))
        (prompt "\nMTEXT is too large, not supported!")
        (prompt "\nGot a sel set of text objects.")
      ) ; endif
    ) ; end while
  ) ; end defun

  ;;  test for valid pre selected selection set
  (if (null (setq ss (getpickfirst (list "TEXT" "MTEXT"))))
    ;;  no set so get user input
    (while ; loop until point is picked
      (not
        (setq
          pt
           (getpoint "\nSelect Text to Increment or select a group of text.")))
       (princ "\nPlease try again...")
    )
  ) ; endif

  (cond
    ;;=================================================
    (ss ; selection already made
     (got_ss ss) ; process the selection set
    ) ; end cond 1
   
    ;;=================================================
    ((and (setq ss (ssget pt '((0 . "TEXT,MTEXT"))))
          (= (sslength ss) 1)
     ) ; if >1 force user to get a set
     ;; user picked a single text object
     ;;(setq ent (ssname ss 0))
     ;;(if (cdr (assoc 3 (entget ent)))
     ;;  (prompt "\nMTEXT is too large, not supported!")
     ;;  (prompt "\nGot a single text object.")
     ;;) ; endif
     (got_ss ss) ; process the selection set
    ) ; end cond 2

    ;;=================================================
    ;; No text selected so get a selection set
    ((and (null (initget 32))
          (setq pt2 (getcorner pt)) ; user to pick window corner
          (setq ss (ssget "_W" pt pt2 '((0 . "TEXT,MTEXT"))))
     )
     (got_ss ss) ; process the selection set
    ) ; end cond 3

    ((prompt "\n*-*  Not Text, Try again. *-*")
    ) ; end cond 3
  ) ; end cond stmt
  (princ)
); end defun
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.

JohnK

  • Administrator
  • Seagull
  • Posts: 10636
Minimum Clicks with ssget
« Reply #12 on: September 12, 2004, 06:57:39 PM »
As far as the selecting the objects already selected; Go to my web site and check out the Selected-p and Get-Selected functions. I worked out some some prety cool code. Monday ill see if i cooked up any beter versions that i didnt post.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #13 on: September 12, 2004, 08:01:07 PM »
A link would be nice, John :D

CAB, here's a little alternative method to play with. It allows for normal exit by the user and returns either a text entity or a selection of text - or nil if exited, of course. Try it out.

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))
        )
      )
    )
  )
  ;; return entity or selection set
  (cond (ent)(ss))
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #14 on: September 12, 2004, 08:10:17 PM »
Quote from: Se7en
As far as the selecting the objects already selected; Go to my web site and check out the Selected-p and Get-Selected functions. I worked out some some prety cool code. Monday ill see if i cooked up any beter versions that i didnt post.


I removed some extra code from your function.

Code: [Select]
(defun Get-Selcted (/ x idx xlist)
  ;; x is nil if nothing is already selected
  (if (setq x (cadr (ssgetfirst)))
    (progn ; at least one obj in x
      ;;(sssetfirst nil)
      (setq idx (sslength x))
      (while (>= (setq idx (1- idx)) 0)
        ;;  make a list
        (setq xlist (cons (ssname x idx) xlist))
        ;;(redraw (ssname x idx) 3)
      ); end while
      (if(>(length xlist)1) xlist (car xlist))
    ); progn
    ;; ELSE need to select something
    (progn
      (while (not (setq x (entsel "\nselect object: "))))
      (redraw (car x) 3)
      (car x) ; return entity
    ); progn
  ); endif
); defun

(defun c:test(/ a)
  (setq a (get-Selcted))
  (princ)
)
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.