Jump to content

Selection Set - mouse 'click' selection order


Steven P

Recommended Posts

Stumped on this one today. I want to record the direction a user selects objects for a selection set - top to bottom or bottom to top - but can't work it out - wonder if anyone has that handy that they can share? Thinking to record the points used for selection.

 

The variable 'lastpoint (my first thought) appears - for me - to only record points outside of a selection set, for example

(princ (getvar 'lastpoint))

(setq MySS (ssget))

(princ (getvar 'lastpoint))

will return for example (123 456) (123 456)

 

 

I could do a loop select points, and then a ssadd to a selection set using say, ssget and crossing filter with the points - but that looks a bit long if there is a simple way to record the points. Wonder if grread will work with ssget nested inside?

 

 

End goal, select lines from a converted PDF to change to a text string (lines are text that is exploded), wanting the user to select bottom to top or top to bottom to set the new text orientation

 

Thanks in advance

 

 

Link to comment
Share on other sites

Get and compare the Y coordinates of the selected objects, then determine if they increase or decrease?

  • Like 1
Link to comment
Share on other sites

The ssnamex function has information about how the objects are selected.

Is that what you need?

  • Like 1
Link to comment
Share on other sites

I tried something similar once, using ssnamex, you can get 4 points of selection rectangle by which you created selection set. Points are not in clicking order,  they go from top left to bottom right I think, but then using  (getvar 'lastpoint) you can determine which point was first by choosing diagonal value from the last one.

Here is the code to get 4 selection rectangle points:

(setq p1 (car (cdr (nth 1 (car (cdr (ssnamex ss 0)))))))
(setq p2 (car (cdr (nth 2 (car (cdr (ssnamex ss 0)))))))
(setq p3 (car (cdr (nth 3 (car (cdr (ssnamex ss 0)))))))
(setq p4 (car (cdr (nth 4 (car (cdr (ssnamex ss 0)))))))


EDIT: just tested and (getvar 'lastpoint) doesn't save last clicked point when selecting ss. I needed selection from left to right on the x axis. So not sure how to determine selection clicking order.

Edited by lastknownuser
  • Like 1
Link to comment
Share on other sites

I was finding that 'lastpoint was giving me points before the selection set was started,

 

Dexus - looks promising, ssnamex returns a list, first number in the list item for each entity appears to be the pick method - individual (1), top to bottom (2), bottom to top (3)? Is that how it works? (sorry, lunchtime here and got to pop out - not taking the time to work it out as I should just now)

Link to comment
Share on other sites

The output is not the easiest to work with, but this is where selection info can be found. Below is an example of (ssnamex (ssget) nil) output:

(
  (3 <Entity name: 7ff4e09ab590> 6 -1) ; Selection Method was CPolygon (crossing box), coordinates of that box can be found in register -1 (below)
  (1 <Entity name: 7ff4e0914110> 1 (0 (-6175.99 -15087.3 318.468))) ; Second item's selection method was pick (just single click), point is found as last item
  (-1 ; This register is referenced above and is a lost of the points selected.
    (0 (-5587.01 -14847.0 318.468))
    (0 (-5283.91 -14847.0 318.468)) ; A point... not that if it was selected from another ucs, the ucs will be added after every point
    (0 (-5283.91 -15046.5 318.468))
    (0 (-5587.01 -15046.5 318.468)))
 )
  • Like 1
Link to comment
Share on other sites

Hmm, I just noticed that the selection window is always referenced the same way no matter where you started selecting.

It seems to always be: Top Left, Top Right, Bottom Right, Bottom Left.

So not as useful for your question. 😐

Link to comment
Share on other sites

I had a quick look earlier, the 1, 2, 3 before <Entity name: kind of matched left to right, or right to left selection which would work for horizontal text (normal or mirrored for my application above): 1 individual picked, 2 left to right, 3 right to left but not sure how to get the vertical points from that. 

Link to comment
Share on other sites

This is just basic using the Y coordinates...

 

Those other methods are too advanced for me.

 

Works correct for mouse clicks on the object (tested lines and plines), reports opposite for window selection, It's over my head to make both work...

 

;;; Gives the vertical selection order of mouse clicks on objects. (bottom to top or top to bottom)

(defun c:ChckSelOrder (/ ss i ent pt y-list y-ordered order)
  
  (setq ss (ssget))

  
  (if (not ss)
    (princ "\nNo objects selected.")
    (progn
      
      (setq y-list '())

      ;; Extract Y-coordinates of the selected objects
      (setq i 0)
      (repeat (sslength ss)
	(setq ent (ssname ss i))
	;; Check if the entity has a valid insertion point
	(setq pt (cdr (assoc 10 (entget ent))))
	(if pt
	  ;; Extract Y-coordinate
	  (setq y-list (cons (cadr pt) y-list))
	  ;; If insertion point is not available
	  (princ (strcat "\nEntity "
			 (itoa i)
			 " does not have a valid insertion point."
		 )
	  )
	)
	(setq i (1+ i))
      )

      ;; Check if y-list has more than one coordinate to compare
      (if (> (length y-list) 1)
	(progn
	  ;; Output the raw Y-coordinates
	  (princ "\nRaw Y-coordinates: ")
	  (princ y-list)

	  ;; Sort Y-coordinates in descending order for comparison
	  (setq y-ordered (vl-sort y-list '>))

	  ;; Output the sorted Y-coordinates
	  (princ "\nSorted Y-coordinates: ")
	  (princ y-ordered)

	  ;; Compare the original and sorted lists to determine order
	  (if (equal y-list y-ordered)
	    (setq order "Objects were selected from bottom to top.")
	    (setq order "Objects were selected from top to bottom.")
	  )

	  ;; Output result
	  (princ (strcat "\n" order))
	)
	(princ "\nNot enough objects to determine order.")
      )
    )
  )

  (princ)
)

 

  • Like 1
Link to comment
Share on other sites

5 hours ago, SLW210 said:

This is just basic using the Y coordinates...

 

Those other methods are too advanced for me.

 

Works correct for mouse clicks on the object (tested lines and plines), reports opposite for window selection, It's over my head to make both work...

 

Works most of the time - haven't had time to work out why tonight but looks promising, thanks

  • Thanks 1
Link to comment
Share on other sites

Maybe another. Then look at X & Y work out direction.

 

(setq pt1 (getpoint "\nPick 1st point "))
(setq pt2 (getcorner pt1 '\nPick second point "))

 

  • Like 1
Link to comment
Share on other sites

12 hours ago, Steven P said:

 

Works most of the time - haven't had time to work out why tonight but looks promising, thanks

It started for something similar with the scanned PDF conversions and Raster Design I "was" working on, so I quickly adjusted it. 

 

It took a lot of reading and learning to get it that far. I need to work it for X direction next, anything you tweak I would be interested in hearing back.

 

Worst part of my job, priorities change daily this time of year.  

Link to comment
Share on other sites

Yes, likewise - Friday I had time to spend time on this, this week not so much, 

Link to comment
Share on other sites

Posted (edited)

Working through the above - still got to get into your minds how it all works out.

 

Anyway, put this one together getting the selection orders by blunt force, select 1 or 2 points, add anything within the points to the selection set, use the 2 points to work out direction, but like BigAl was suggesting.

 

Not the prettiest and doesn't mimic ssget fully (yet...)

 

(defun c:test ( / )
  (setq MySS (ssadd))
  (while (setq pt1 (getpoint "\nSelect Objects:"))
    (if (setq MyEnt (car (nentselp pt1)))
      (progn
        (if (ssdel MyEnt MySS)
          (progn
            (redraw MyEnt 4)
          )
          (progn
            (setq MySS (ssadd MyEnt MySS))
            (princ (strcat " 1 Found, "))
            (redraw MyEnt 3)
          ) ; end progn
        ) ; end if ssdel
      ) ; end progn
      (progn
        (setq pt2 (getpoint " Specify Opposite Corner"))
        (if (< (car pt1)(car pt2)) ; window or crossing
          (setq SelSS (ssget "_W" pt1 pt2) )
          (setq SelSS (ssget "_C" pt1 pt2) )
        )
        (setq acount 0)
        (if SelSS
        (progn
          (princ (strcat " " (rtos (sslength SelSS) 2 0) " Found, "))
          (while (< acount (sslength SelSS))
            (setq MySS (ssadd (ssname SelSS acount) MySS))
            (redraw (ssname SelSS acount) 3)
            (setq acount (+ acount 1))
          ) ; end while
        ) ; end progn
        ) ; end if SelSS
      ) ; end progn
    ) ; end if MyEnt

    (if (< (cadr pt1)(cadr pt2)) ; window or crossing
      (princ "L")
      (princ "U")
    )
    (if (< (car pt1)(car pt2)) ; window or crossing
      (princ "L")
      (princ "R")
    )
  ) ; end while

  (setq acount 0) ; clear highlights
  (while (< acount (sslength MySS))
    (redraw (ssname MySS acount) 4)
    (setq acount (+ acount 1))
  )

  (princ)
)

 

Edited by Steven P
Link to comment
Share on other sites

Small update to what I had above - this is looking more like ssget that we are used to. Written as a sub function to allow entity types filter on the ssget. This returns only the last mouse click direction - need to work out what I want with many selections made.

 

 

(defun SSMouseOrder ( EntTypeList / MyList MySS pt1 pt2 MyEnt SelSS MySS MyDuir acount)
;; Enttypelist: wildcards are OK but not for single selection.
;; Enttypelist in CAPITALS for single entity selection to work.

;;Set up LISP
  (setq MySS (ssadd))                          ;; Blank Selelection Set
  (if (= EntTypeList nil)(setq EntTypeList (list "LINE" "ARC" "CIRCLE")) ) ;; default entity filter

  (setq MyList (list (cons -4 "<OR") ))        ;; Create filter to use with ssget
  (foreach n EntTypeList
    (setq MyList (append MyList (list (cons 0 n)) ) )
  ) ; end foreach
  (setq MyList (append MyList (list (cons -4 "OR>")) ) )

  (while (setq pt1 (getpoint "Select Objects:"));; Loop to select entities
    (if (setq MyEnt (car (nentselp pt1)))       ;; If 1st point selected was on an entity: Single entity selected
      (progn
        (if (ssdel MyEnt MySS)                  ;; If entity is in selected selection set, delete it
          (progn
            (redraw MyEnt 4)                    ;; Take away highlight
          )
          (progn                                ;; Else add single entity to selection set
            (If (member (cdr (assoc 0 (entget MyEnt))) EntTypeList) ;;Check entity type is desired
              (progn
                (setq MySS (ssadd MyEnt MySS))  ;; Add to selection set
                (princ (strcat " 1 Found, "))   ;; Report selection found
                (redraw MyEnt 3)                ;; highlight entity
              ) ; end progn
            ) ; end if member
          ) ; end progn
        ) ; end if ssdel
      ) ; end progn
      (progn                                    ;; Else if clicked point not an entity
        (setq pt2 (getcorner pt1 " Specify Opposite Corner")) ;;get 2nd point
        (if (< (car pt1)(car pt2))              ;; Left to right, right to left to determine window or crossing filter
          (setq SelSS (ssget "_W" pt1 pt2 MyList) ) ;; Get selected entities
          (setq SelSS (ssget "_C" pt1 pt2 MyList) )
        )
        (setq acount 0)
        (if SelSS                               ;; If anything was selected
        (progn
          (princ (strcat " " (rtos (sslength SelSS) 2 0) " Found, ")) ;; report how many entities selected
          (while (< acount (sslength SelSS))   ;; add entities to selection set
            (setq MySS (ssadd (ssname SelSS acount) MySS))
            (redraw (ssname SelSS acount) 3)   ;; Highlight each entity
            (setq acount (+ acount 1))         ;; Loop counter
          ) ; end while
        ) ; end progn
        ) ; end if SelSS
      ) ; end progn
    ) ; end if MyEnt

    (setq MyDir 0)                             ;; Work out mouse click directions. Note single selection direction is LL->UR
    (if (< (cadr pt1)(cadr pt2))               ;; Horizontal
      (setq MyDir 0)
      (setq MyDir 1)
    )
    (if (< (car pt1)(car pt2))                 ;; Vertical
      (setq MyDir (+ MyDir 0))
      (setq MyDir (+ MyDir 2))
    )
  ) ; end while

  (setq acount 0)                             ;; clear highlights
  (while (< acount (sslength MySS))
    (redraw (ssname MySS acount) 4)
    (setq acount (+ acount 1))
  )

  (if (= (sslength MySS) 0)                   ;; report the selection set and direction or nil if no selection
    nil
    (list MySS MyDir)                         ;; MyDir: 0 BL->TR (or point selection), 1 TL->BR, 2 BR->TL, 3 TR->BL
  )
)

 

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