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
Thanks,
Robert
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