Steven P Posted August 20 Posted August 20 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 Quote
SLW210 Posted August 20 Posted August 20 Get and compare the Y coordinates of the selected objects, then determine if they increase or decrease? 1 Quote
dexus Posted August 20 Posted August 20 The ssnamex function has information about how the objects are selected. Is that what you need? 1 Quote
lastknownuser Posted August 20 Posted August 20 (edited) 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 August 20 by lastknownuser 1 Quote
Steven P Posted August 20 Author Posted August 20 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) Quote
dexus Posted August 20 Posted August 20 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))) ) 1 Quote
dexus Posted August 20 Posted August 20 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. Quote
Steven P Posted August 20 Author Posted August 20 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. Quote
SLW210 Posted August 20 Posted August 20 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) ) 1 Quote
Steven P Posted August 20 Author Posted August 20 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 1 Quote
BIGAL Posted August 20 Posted August 20 Maybe another. Then look at X & Y work out direction. (setq pt1 (getpoint "\nPick 1st point ")) (setq pt2 (getcorner pt1 '\nPick second point ")) 1 Quote
SLW210 Posted August 21 Posted August 21 14 hours ago, rlx said: maybe something like this contains parts for you to use I forgot about that thread. I'll have to look it over again. Quote
SLW210 Posted August 21 Posted August 21 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. Quote
Steven P Posted August 21 Author Posted August 21 Yes, likewise - Friday I had time to spend time on this, this week not so much, Quote
Steven P Posted August 21 Author Posted August 21 (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 August 21 by Steven P Quote
Steven P Posted August 22 Author Posted August 22 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 ) ) Quote
Recommended Posts
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.