Selection Set Bounding Box
Function Syntax | (LM:ssboundingbox <sel>) |
Current Version | 1.2 |
Donate |
Arguments | ||
---|---|---|
Symbol | Type | Description |
sel | Selection Set | Selection set for which to return the bounding box |
Returns | ||
Type | Description | |
List | List of lower-left & upper-right WCS coordinates of bounding box |
Function Description
This function will return a list of the lower-left and upper-right coordinates (in WCS) of the rectangular frame describing the bounding box of all objects in the supplied selection set.
In this context, the bounding box is defined as the smallest rectangular cuboid with sides parallel to the three WCS coordinate axes which encloses all objects in the set.
Note that this bounding box does not necessarily correspond to the rectangular frame with the smallest possible area which could enclose the objects in the set, as the edges are always parallel to the WCS coordinate axes.
;; Selection Set Bounding Box - Lee Mac ;; Returns a list of the lower-left and upper-right WCS coordinates of a ;; rectangular frame bounding all objects in a supplied selection set. ;; sel - [sel] Selection set for which to return bounding box (defun LM:ssboundingbox ( sel / idx llp ls1 ls2 obj urp ) (repeat (setq idx (sslength sel)) (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx))))) (if (and (vlax-method-applicable-p obj 'getboundingbox) (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'llp 'urp)))) ) (setq ls1 (cons (vlax-safearray->list llp) ls1) ls2 (cons (vlax-safearray->list urp) ls2) ) ) ) (if (and ls1 ls2) (mapcar '(lambda ( a b ) (apply 'mapcar (cons a b))) '(min max) (list ls1 ls2)) ) )
Alternative Version
This alternative version of the function avoids the limitation imposed by the maximum number of arguments accepted by the AutoLISP min & max functions when processing selection sets containing a large number of objects:
;; Selection Set Bounding Box - Lee Mac ;; Returns a list of the lower-left and upper-right WCS coordinates of a ;; rectangular frame bounding all objects in a supplied selection set. ;; sel - [sel] Selection set for which to return bounding box (defun LM:ssboundingbox ( sel / idx llp ls1 ls2 obj urp ) (repeat (setq idx (sslength sel)) (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx))))) (if (and (vlax-method-applicable-p obj 'getboundingbox) (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'llp 'urp)))) ) (setq ls1 (mapcar 'min (vlax-safearray->list llp) (cond (ls1) ((vlax-safearray->list llp)))) ls2 (mapcar 'max (vlax-safearray->list urp) (cond (ls2) ((vlax-safearray->list urp)))) ) ) ) (if (and ls1 ls2) (list ls1 ls2)) )
Test Program
The following program will prompt the user to select a set of objects and will then construct a bounding box surrounding all objects in the selection.
If all objects in the selection are coplanar and reside in a plane parallel to the WCS plane, the following program will construct the 2D rectangular bounding box in the form of a 2D LWPolyline; if any object in the selection resides in a different construction plane, the program will construct the 3D cuboid bounding box in the form of a 3D solid.
(defun c:test ( / box obj sel spc ) (if (and (setq sel (ssget)) (setq box (LM:ssboundingbox sel)) ) (progn (setq spc (vlax-get-property (vla-get-activedocument (vlax-get-acad-object)) (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace ) ) ) (if (equal 0.0 (apply '- (mapcar 'caddr box)) 1e-6) (progn (setq obj (vlax-invoke spc 'addlightweightpolyline (apply 'append (mapcar '(lambda ( x ) (mapcar '(lambda ( y ) ((eval y) box)) x)) '( (caar cadar) (caadr cadar) (caadr cadadr) (caar cadadr) ) ) ) ) ) (vla-put-closed obj :vlax-true) (vla-put-elevation obj (caddar box)) ) (apply 'vlax-invoke (vl-list* spc 'addbox (apply 'mapcar (cons '(lambda ( a b ) (/ (+ a b) 2.0)) box)) (apply 'mapcar (cons '- (reverse box))) ) ) ) ) ) (princ) ) (vl-load-com) (princ)