Weird ssget "_W" behavior?

Weird ssget "_W" behavior?

CodeDing
Advisor Advisor
1,231 Views
9 Replies
Message 1 of 10

Weird ssget "_W" behavior?

CodeDing
Advisor
Advisor

Hello all,

 

I was trying to think of something to help a user with their question here:

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/determining-if-an-object-is-outside-...

 

And I'm under the impression that this code SHOULD return T only if an entity is entirely within the current viewport view. But when I test it, I am getting T even when it is partially within view. My "View:LL-UR" function appears to be returning the correct coordinates, therefore I am under the impression that perhaps the "_W" functionality of ssget is acting incorrectly? Can someone either help confirm this or tell me where I'm messing up? Just pass an entity name into the function.

 

(defun IsEntityInView (e / View:LL-UR corners ss)
  (defun View:LL-UR ( / h w c)
    (setq h (getvar 'VIEWSIZE))
    (setq w (* 0.5 (* h (apply '/ (getvar 'SCREENSIZE)))))
    (setq h (* 0.5 h))
    (setq c (getvar 'VIEWCTR))
    (list
      (mapcar '- c (list w h))
      (mapcar '+ c (list w h))
    );list
  );defun
  (setq corners (VIEW:LL-UR))
  (or
    (member
      e
      (vl-remove-if
        'listp
        (mapcar
          'cadr
          (ssnamex (if (setq ss (ssget "_W" (car corners) (cadr corners))) ss (ssadd)))
        );mapcar
      );vl
    );member
  );or
);defun

 

Using:

Civil 3D 2019

 

Thanks.

Best,

~DD

0 Likes
Accepted solutions (2)
1,232 Views
9 Replies
Replies (9)
Message 2 of 10

Kent1Cooper
Consultant
Consultant

It has been my understanding that if all of an object that is visible in the viewing area is within a selection window, the object is selected even though part of it extends beyond.  That sounds like what's happening.  I've only encountered it when done manually, but I haven't had occasion to try it in an (ssget) window.

 

If that's the cause, here's a possible workaround, for most entity types:  Establish the window of the current viewing area, then before using the (ssget), Zoom .99X so that the new viewing area will be slightly larger than the selection window, and such an object will have some part visible that is not within the selection window.  Zoom P afterwards to go back if you like.

 

However, even that would be "fooled" by an object such as a Block of separated pieces, or sometimes Mtext of multiple lines, which even after the Zooming out a little could still have all of what's visible of it within the selection window.

Kent Cooper, AIA
0 Likes
Message 3 of 10

CodeDing
Advisor
Advisor

Appreciate the reply Kent. But my issue does not appear to be one of a 'close' view scale. I was testing with primarily polylines and had multiple instances when multiple vertices were plenty far outside the current view extents and it was returning true. Also when a vertical polyline only had about 1/3 of the entity inside the view it was still returning true. If anybody gets some time to confirm or deny this behaviour or to tell me that I fudged some coding, it would be appreciated 👍

 

Best,

~DD

0 Likes
Message 4 of 10

hmsilva
Mentor
Mentor

@CodeDing 

the Window Polygon mode, works as expected, selects only objects completely inside the polygon defined by the points list.

 

Hope this helps,
Henrique

EESignature

Message 5 of 10

Kent1Cooper
Consultant
Consultant
Accepted solution

@CodeDing wrote:

.... multiple instances when multiple vertices were plenty far outside the current view extents and it was returning true. Also when a vertical polyline only had about 1/3 of the entity inside the view it was still returning true. ....


I have now experimented a little, and yes, anything with all that is visible of it inside the selection window gets selected.  It doesn't matter how far outside the viewing area it extends.  If the selection window is the viewing area, everything visible will be selected.  But I tried establishing the selection window from the viewing area, then backing off a hair, so that the selection window was a hair smaller than the new viewing area, and things that extended beyond that selection window were in fact not selected, as expected.

Kent Cooper, AIA
Message 6 of 10

CodeDing
Advisor
Advisor

Ok I will have to test Sunday or Monday. Thank you for looking into it further.

0 Likes
Message 7 of 10

ВeekeeCZ
Consultant
Consultant

Agreed with Kent - unless you have 2017+ with its SELECTIONOFFSCREEN feature set to no limits.

0 Likes
Message 8 of 10

CodeDing
Advisor
Advisor

@Kent1Cooper ,

 

I hate that this is a thing haha. But you're right.. If I zoom by 0.99x or even select only 0.99% of the full screen size, it works correctly. Dumb, but it works. Thank you.

 

Best,

~DD

0 Likes
Message 9 of 10

ronjonp
Mentor
Mentor

@CodeDing If you don't want to mess with the zoom, as @hmsilva brought up, window polygon selection works. Hope you don't mind, I also changed the member check to vl-some so it will stop processing if it finds a match. This should be more efficient on larger selection sets. 🍻

 

 

(defun isentitycompletelyinview	(e / view:ll-ur corners ss)
  ;; RJP mod to use window polygon and vl-some for check
  (defun view:ll-ur (/ h w c)
    (setq h (getvar 'viewsize))
    (setq w (* 0.5 (* h (apply '/ (getvar 'screensize)))))
    (setq h (* 0.5 h))
    (setq c (getvar 'viewctr))
    (list (mapcar '- c (list w h))
	  (list (+ w (car c)) (- (cadr c) h))
	  (mapcar '+ c (list w h))
	  (list (- (car c) w) (+ h (cadr c)))
    )
  )
  (setq corners (view:ll-ur))
  ;; (grdraw (cadr corners) (cadddr corners) 1)
  ;; (grdraw (car corners) (caddr corners) 3)
  (and (setq ss (ssget "_WP" corners))
       (vl-some '(lambda (x) (equal e x)) (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
  )
)
;; (setq e (car (entsel)))
(isentitycompletelyinview e)

 

 

 

Message 10 of 10

ronjonp
Mentor
Mentor
Accepted solution

Better yet 🙂

 

(defun isentitycompletelyinview	(e / view:ll-ur corners ss)
  ;; RJP mod to use window polygon and ssdel for check
  (defun view:ll-ur (/ h w c)
    (setq h (getvar 'viewsize))
    (setq w (* 0.5 (* h (apply '/ (getvar 'screensize)))))
    (setq h (* 0.5 h))
    (setq c (getvar 'viewctr))
    (list (mapcar '- c (list w h))
	  (list (+ w (car c)) (- (cadr c) h))
	  (mapcar '+ c (list w h))
	  (list (- (car c) w) (+ h (cadr c)))
    )
  )
  (setq corners (view:ll-ur))
  ;; (grdraw (cadr corners) (cadddr corners) 1)
  ;; (grdraw (car corners) (caddr corners) 3)
  (and (setq ss (ssget "_WP" corners)) (ssdel e ss))
)
;; (setq e (car (entsel)))
(isentitycompletelyinview e)