Extmin/Extmax for only objects selected?

Robert Grandmaison

Usenet Archive
Joined
Jul 8, 2003
Messages
7
Reaction score
0
Is there an easy, quick way of getting the minimum XYZ and maximum XYZ values for a selection set?

Thanks,

Robert
 
don't know if you consider it easy or quick, but you get the bounding box for each item, save the least and most points as variables, checking each ents least and most against them and updating if necessary, and when you're done you have the least and most of the whole grouping or I suppose you could make a block out of them, get the bounding box for the block, and then explode and purge the temp block?
 
lol, I know I can do that- was hoping for some kind of VLA trick! The operative word there was EASY! ; )

Robert
 
Well, part of it may be a matter of understanding how you're getting your list of points and then creating a selection set of them?

Are you trying to get the min/max XYZ of a selection set of objects? Or are you somehow generating a selection set of point lists?

(vl-sort) may be what you're looking for, but you'll need to make the appropriate list/selection set. Also, what are you looking for? the min/max X, Y, or Z? or of each?

You've left this fairly vague. :)
 
Okay, I'll be more specific! I want to allow a user to select multiple objects and then return the minimum and maximum XYZ points that would be required to place a bounding box around those objects.

Specifically, I want to build a "zoom to objects" kind of thing. I was hoping there was an easy way to do this via properties and selection sets, rather than having to sort through/compare/replace potentially long lists of object point values with lower ones.

Robert
 
Sorry, didn't mean to prod... just thought that if there were a little more information, there might be a little more clarity for someone to help you, or someone may very well have a routine already done they can share. I apologize that I don't already, but I'm always willing to help when I can.
 
Yes you can do that fairly easily, the vla function you're after is vla-getboundingbox. Step through the selection set, do a vla-getboundingbox on each and check if the min/max points are smaller/bigger than the previous entities' points. Regards, Dave
 
Just starting to get the hang of this vlisp stuff.

;;Joe Burke 7/8/2003
;;zoom to selection set bounding box
(defun C:ZoomSS ( / SS i Vobj PtLst MinPt MaxPt Pts)
(if (not (setq SS (ssget "I")))
(progn
(princ "\nSelect objects to zoom: ")
(setq SS (ssget))
)
)
(and SS
(setq i 0)
(repeat (sslength SS)
(setq Vobj (vlax-ename->vla-object (ssname SS i)))
(vla-getboundingbox Vobj 'MinPt 'MaxPt)
(setq PtLst (cons (vlax-safearray->list MinPt) PtLst))
(setq PtLst (cons (vlax-safearray->list MaxPt) PtLst))
(setq i (1+ i))
)
(setq Pts
(mapcar '(lambda (x) (trans x 0 1)) ;wcs to ucs
(list (apply 'mapcar (cons 'min PtLst))
(apply 'mapcar (cons 'max PtLst))
)
)
)
)
(command "_zoom" "w" (car Pts) (cadr Pts) "zoom" ".9x") ;(sssetfirst nil SS) (princ)
) ;end
 
Yes sir  :-)

 

Joe

"morrisde" <> wrote:

Yes you can do that fairly easily, the vla function you're after is vla-getboundingbox. Step through the selection set, do a vla-getboundingbox on each and check if the min/max points are smaller/bigger than the previous entities' points. Regards, Dave
 
Nice work, Joe & Tony.
The nasty downside is how to deal with twisted views since the bounding box is always orthogonal to the WCS. I finally built a PLBoundingBox function for polylines in a twisted view, but the rest of the object domain is more than I care to take on. Well, at least we could handle circles okay. :/
 
Thanks, John :-)

I don't quite follow the twisted view problem. I see the function I posted doesn't work right in some cases given a twisted view, but why isn't clear to me. In a twisted view you are still in WCS, right?

Anyway, here's a revised version which tries to fix the problem. It's a bit of a hack, designed primarily so it's obvious what I'm trying to do. It seems to work. Though frankly, I don't know much about twisted views. When I want to do this, I rotate the UCS.

Joe

;;Joe Burke revised 7/9/2003
;;zoom to selection set bounding box
(defun C:ZoomSS ( / SS i Vobj PtLst MinPt MaxPt Pts LL UR) (vl-load-com) (if (not (setq SS (ssget "I"))) (progn (princ "\nSelect objects to zoom: ") (setq SS (ssget)) ) ) (and SS (setq i 0) (repeat (sslength SS) (setq Vobj (vlax-ename->vla-object (ssname SS i))) (vla-getboundingbox Vobj 'MinPt 'MaxPt) (setq PtLst (cons (vlax-safearray->list MinPt) PtLst)) (setq PtLst (cons (vlax-safearray->list MaxPt) PtLst)) (setq i (1+ i)) ) (setq Pts (mapcar '(lambda (x) (trans x 0 1)) ;wcs to ucs (list (apply 'mapcar (cons 'min PtLst)) (apply 'mapcar (cons 'max PtLst)) ) ) ) ;move points out a bit (setq LL (car Pts) UR (cadr Pts) LL (polar UR (angle UR LL) (* 1.1 (distance LL UR))) UR (polar LL (angle LL UR) (* 1.1 (distance LL UR))) )
) ;and

(if (not (equal 0.0 (getvar "viewtwist")))
(progn
(setq RotPts
(RotatePts (list LL UR) (MidPoint LL UR) (getvar "viewtwist"))) (command "_zoom" "w" (car RotPts) (cadr RotPts)) ) (command "_zoom" "w" LL UR) ;else ) ;if (princ)
) ;end

;arguments: point list, base point, angle
(defun RotatePts (plst bp ang)
(mapcar '(lambda (p)
(polar bp (+ (angle bp p) ang) (distance bp p)))
plst
)
)

(defun MidPoint (p1 p2)
(mapcar '/ (mapcar '+ p1 p2) '(2.0 2.0 2.0))
)
;---------------------------
 
Thanks, Steve.

I recall when I was so stupid about this stuff... and you helped me. That exchange might have seemed pointless at the time. It wasn't.

Joe
 
Interesting idea with the RotatePts, but the BoundingBox of any object except a circle will have different widths and heights depending on its orientation. For example, draw a line one unit long at 45 degrees (0,0,0 to 1,1,0). The BoundingBox (W x H) will be 0.707 x 0.707. Now do a DView;Twist by 45 degrees CCW, whatever, to make the line vertical. The BoundingBox relative to the screen should be 0.0 x 1.0, but the BoundingBox method will still return 0.707 x 0.707. It ain't so easy figuring out what the BoundingBox of a collection of objects would be if rotated without actually rotating them first, which I wouldn't recommend tryng in a topographic survey having 35000+ enitities.
 
John,

Given your example, I see the problem. But of course, I don't know how to fix it.

Interesting... ToolPac 7 has a similar command, which does seem to work right given your example. I guess Terry knows something we don't?

Whatever, the problem is a tempest in a teapot as far as I'm concerned since I don't use twisted views.

Here's a more important question. Should I use (vl-catch-all-apply 'function list) somewhere in the program? If so, how to do that is sure a mystery to me. When/if you have time, please show me how given my first post.

Thanks
Joe
 
Doug,

Thanks. That's very interesting. Interesting enough that I went back and tried John's twisted view one unit line example again using the first function I posted. Forget the second one, it's trash. Anyway, here's what I see. Pts is the variable in ZoomSS.

Command: viewtwist
VIEWTWIST = 45.00 (read only)

Command: bounds
1 found
((0.0 0.0 0.0) (0.707107 0.707107 0.0))

Command: zoomss

Command: !pts
((0.0 0.0 0.0) (0.707107 0.707107 0.0))

Which is what John said. But unless I'm mistaken, that's the right answer in this case. Both Z2 and ZoomSS zoom exactly to the ends of the line.

So John, what am I missing here...?

Joe
 
John,

Maybe what I'm missing is just the fact the example you mentioned doesn't demonstrate the problem on screen? Both functions tend to zoom in too far in a twisted view. Testing with a zig-zag pline in a twisted view, I see why now.

Doug,

I probably misread your intent. I thought you were saying "bounds" would fix the twisted view thing. Now I think you were simply demonstrating a different way to arrive at the answer.

Joe < thick as usual
 
What we're both missing is that Doug is a lot smarter than we look. :] I had my head screwed on in the manner of (command "_.zoom" ...) which provides the ugly results I described. Magically, Doug (either by psyche, luck, experimentation, or just plain smarts) found that the 'ZoomWindow method "thinks" the same as its ActiveX brother (er.. sister, cousin, whatever).

Hats off (displaying our vaccuum brains) to Doug!
Okay, okay... feel free to change "we" to "me" etc.
Of course, now I'm sitting here dumbfounded as to what I was trying to do back when I had concluded there was a problem. Dunno, but I just found some code I actually sold back in 01/2002 that used the same approach as Doug's. Sheesh, I wish I could search my brain as easily as my hard drive. :/ Maybe my brain needs defragging.

Then again, I did manage to create some kind of problem...
Command: Z2
Select objects: ALL
4 found

Select objects:
; error: Automation Error. Null extents

We'll have to figure out whazupwithat.
 
Baloney. At best I'm AAA. I figure you'll be called up to the majors pretty soon. Keep slugging. What's neat is that this topic can probably keep any number of us churning our grey matter for a while, unless of course Tony figured all this out 5 years ago.
:)

Joe Burke said:
John,

I'm often seeing this with Z2:

Z2 1 found
error: Automation Error. Calling method AddItems of interface IAcadSelectionSet failed

Surely Doug will know what's up with that.

But maybe you need to do some more testing... or I do. In a twisted view Doug's bounds function returns the same coordinates as the Pts variable in my stuff. So Z2 will sometimes either zoom in too far or not far enough. Depends on the situation. Seems to make sense. If you draw a line using the coordinates... well?

Regarding who knows what, one thing is certain. I'm way out of my league talking to you two. ;-)

Joe

John Uhden said:
What we're both missing is that Doug is a lot smarter than we look. :] I had my head screwed on in the manner of (command "_.zoom" ...) which provides the ugly results I described. Magically, Doug (either by psyche, luck, experimentation, or just plain smarts) found that the 'ZoomWindow method "thinks" the same as its ActiveX brother (er.. sister, cousin, whatever).

Hats off (displaying our vaccuum brains) to Doug!
Okay, okay... feel free to change "we" to "me" etc.
Of course, now I'm sitting here dumbfounded as to what I was trying to do back when I had concluded there was a problem. Dunno, but I just found some code I actually sold back in 01/2002 that used the same approach as Doug's. Sheesh, I wish I could search my brain as easily as my hard drive. :/ Maybe my brain needs defragging.

Then again, I did manage to create some kind of problem...
Command: Z2
Select objects: ALL
4 found

Select objects:
; error: Automation Error. Null extents

We'll have to figure out whazupwithat.

Joe Burke said:
Doug,

Thanks. That's very interesting. Interesting enough that I went back and tried John's twisted view one unit line example again using the first function I posted. Forget the second one, it's trash. Anyway, here's what I see. Pts is the variable in ZoomSS.

Command: viewtwist
VIEWTWIST = 45.00 (read only)

Command: bounds
1 found
((0.0 0.0 0.0) (0.707107 0.707107 0.0))

Command: zoomss

Command: !pts
((0.0 0.0 0.0) (0.707107 0.707107 0.0))

Which is what John said. But unless I'm mistaken, that's the right answer in this case. Both Z2 and ZoomSS zoom exactly to the ends of the line.

So John, what am I missing here...?

Joe

Joe,
I wrote c:bounds Tuesday shortly after Robert posted his query but didn't have time to post it. This morning, I added the C:Z2 function to demonstrate that with ActiveX, the UCS and viewtwist is irrelevant.

(vl-load-com)
;;D. C. Broad, Jr. Demonstration for bounds selection
;;Returns the bounds of a selection set
(defun c:bounds (/ llc urc ll ur ss doc)
(setq doc (vla-get-activedocument (vlax-get-acad-object))) (if (ssget) (progn (setq ss (vla-get-activeselectionset doc)) (vla-getboundingbox (vla-item ss 0) 'll 'ur) (setq llc (vlax-safearray->list ll) urc (vlax-safearray->list ur)) (vlax-for n ss (vla-getboundingbox n 'll 'ur) (setq llc (mapcar 'min llc (vlax-safearray->list ll))) (setq urc (mapcar 'max urc (vlax-safearray->list ur))))
(list llc urc))))

(defun c:z2 ( / bounds)
(setq bounds (c:bounds))
;;unlike the zoom command, vla-zoomwindow uses world
;;coordinate system points to paint the view. This
;;makes the current UCS and viewtwist irrelevant.
(vla-zoomwindow
(vlax-get-acad-object)
(vlax-3d-point (car bounds))
(vlax-3d-point (cadr bounds))
))

John,

Given your example, I see the problem. But of course, I don't know how to fix it.

Interesting... ToolPac 7 has a similar command, which does seem to work right given your example. I guess Terry knows something we don't?

Whatever, the problem is a tempest in a teapot as far as I'm concerned since I don't use twisted views.

Here's a more important question. Should I use (vl-catch-all-apply 'function list) somewhere in the program? If so, how to do that is sure a mystery to me. When/if you have time, please show me how given my first post.

Thanks
Joe

Interesting idea with the RotatePts, but the BoundingBox of any object except a circle will have different widths and heights depending on its orientation. For example, draw a line one unit long at 45 degrees (0,0,0 to 1,1,0). The BoundingBox (W x H) will be 0.707 x 0.707. Now do a DView;Twist by 45 degrees CCW, whatever, to make the line vertical. The BoundingBox relative to the screen should be 0.0 x 1.0, but the BoundingBox method will still return 0.707 x 0.707. It ain't so easy figuring out what the BoundingBox of a collection of objects would be if rotated without actually rotating them first, which I wouldn't recommend tryng in a topographic survey having 35000+ enitities.

Thanks, John :-)

I don't quite follow the twisted view problem. I see the function I

posted
doesn't work right in some cases given a twisted view, but why isn't clear to me. In a twisted view you are still in WCS, right?

Anyway, here's a revised version which tries to fix the problem. It's a bit of a hack, designed primarily so it's obvious what I'm trying to do. It seems to work. Though frankly, I don't know much about twisted views. When I want to do this, I rotate the UCS.

Joe

;;Joe Burke revised 7/9/2003
;;zoom to selection set bounding box
(defun C:ZoomSS ( / SS i Vobj PtLst MinPt MaxPt Pts LL UR) (vl-load-com) (if (not (setq SS (ssget "I"))) (progn (princ "\nSelect objects to zoom: ") (setq SS (ssget)) ) ) (and SS (setq i 0) (repeat (sslength SS) (setq Vobj (vlax-ename->vla-object (ssname SS i))) (vla-getboundingbox Vobj 'MinPt 'MaxPt) (setq PtLst (cons (vlax-safearray->list MinPt) PtLst)) (setq PtLst (cons (vlax-safearray->list MaxPt) PtLst)) (setq i (1+ i)) ) (setq Pts (mapcar '(lambda (x) (trans x 0 1)) ;wcs to ucs (list (apply 'mapcar (cons 'min PtLst)) (apply 'mapcar (cons 'max PtLst)) ) ) ) ;move points out a bit (setq LL (car Pts) UR (cadr Pts) LL (polar UR (angle UR LL) (* 1.1 (distance LL UR))) UR (polar LL (angle LL UR) (* 1.1 (distance LL UR))) )
) ;and

(if (not (equal 0.0 (getvar "viewtwist")))
(progn
(setq RotPts
(RotatePts (list LL UR) (MidPoint LL UR) (getvar "viewtwist"))) (command "_zoom" "w" (car RotPts) (cadr RotPts)) ) (command "_zoom" "w" LL UR) ;else ) ;if (princ)
) ;end

;arguments: point list, base point, angle
(defun RotatePts (plst bp ang)
(mapcar '(lambda (p)
(polar bp (+ (angle bp p) ang) (distance bp p)))
plst
)
)

(defun MidPoint (p1 p2)
(mapcar '/ (mapcar '+ p1 p2) '(2.0 2.0 2.0))
)
;---------------------------

Nice work, Joe & Tony.
The nasty downside is how to deal with twisted views since the bounding box is always orthogonal to the WCS. I finally built a PLBoundingBox function for polylines in a twisted view, but the rest of the object domain is more than I care to take on. Well, at least we could handle circles okay. :/

Just starting to get the hang of this vlisp stuff.

;;Joe Burke 7/8/2003
;;zoom to selection set bounding box
(defun C:ZoomSS ( / SS i Vobj PtLst MinPt MaxPt Pts)
(if (not (setq SS (ssget "I")))
(progn
(princ "\nSelect objects to zoom: ")
(setq SS (ssget))
)
)
(and SS
(setq i 0)
(repeat (sslength SS)
(setq Vobj (vlax-ename->vla-object (ssname SS i)))
(vla-getboundingbox Vobj 'MinPt 'MaxPt)
(setq PtLst (cons (vlax-safearray->list MinPt) PtLst))
(setq PtLst (cons (vlax-safearray->list MaxPt) PtLst))
(setq i (1+ i))
)
(setq Pts
(mapcar '(lambda (x) (trans x 0 1)) ;wcs to ucs
(list (apply 'mapcar (cons 'min PtLst))
(apply 'mapcar (cons 'max PtLst))
)
)
)
)
(command "_zoom" "w" (car Pts) (cadr Pts) "zoom" ".9x") ;(sssetfirst nil SS) (princ)
) ;end

Okay, I'll be more specific! I want to allow a user to select multiple objects and then return the minimum and maximum XYZ points that would be required to place a bounding box around those objects.

Specifically, I want to build a "zoom to objects" kind of thing. I was hoping there was an easy way to do this via properties and selection sets, rather than having to sort through/compare/replace potentially long lists of object point values with lower ones.

Robert
 

Latest threads

Back
Top