Grrr Posted April 12, 2021 Posted April 12, 2021 Hey guys, So I have a block reference in ModelSpace, and a Viewport located on a Layout with 5-6 other viewports. I was trying to write a subfunction that would zoom that certain viewport to the bounding box's of that block reference. I've never dealt with VIEWPORTS, So I currently assembled this sub, from @rlx's code which works as I've expected: ; Currently using this : ; (ViewportZoomToBlockReference "header" (vlax-ename->vla-object (car (entsel)))) (defun ViewportZoomToBlockReference ( BlockRefName VportObj / BlockRefName oldcmdecho vplist curcvport nr vpss ms en x SS blk ll ur ) (cond ( (not (tblsearch "BLOCK" BlockRefName)) (princ (strcat "\nUnable to find " BlockRefName " block definition")) ) ( (not ( (lambda ( / ctab ) (setq ctab (getvar 'ctab)) (setvar 'ctab "Model") (setq SS (ssget "_X" (list (cons 0 "INSERT") (cons 2 BlockRefName) (if (= 1 (getvar 'cvport)) (cons 410 (getvar 'ctab)) '(410 . "Model"))))) (setvar 'ctab ctab) SS ); lambda ) ) (princ (strcat "\nUnable to obtain selection for " BlockRefName " blocks")) ) ( (not (setq blk (vlax-ename->vla-object (ssname SS 0)))) ) (t (setq oldcmdecho (getvar "cmdecho"))(setvar "cmdecho" 0)(setq vplist (mapcar 'car (vports)))(setq curcvport (getvar "cvport")) (if (= (getvar "tilemode") 0) (progn (if (= (setq ms (getvar "cvport")) 1)(command "._mspace")) (setq nr 0 vpss (ssget "_x" (list '(-4 . "<AND") '(0 . "VIEWPORT")(cons 410 (getvar "ctab")) '(-4 . "<NOT") '(69 . 1) '(-4 . "NOT>") '(-4 . "AND>")))) (setq en (entget (vlax-vla-object->ename VportObj))) (if (and (= 0 (logand 1 (cdr (assoc 90 en))))(< 0 (cdr (assoc 68 en)))(/= 16384 (logand 16384 (cdr (assoc 90 en))))) (progn (setvar "cvport" (cdr (assoc 69 en))) (vla-GetBoundingBox blk 'll 'ur) (vla-ZoomWindow (vlax-get-acad-object) ll ur) ) ) (if (= ms 1) (command "._pspace")) ) ; (foreach x vplist (setvar "cvport" x) (command "._zoom" "_e")) ) (setq vpss nil)(setvar "cvport" curcvport)(setvar "cmdecho" oldcmdecho) ); t ); cond ); ViewportZoomToBlockReference Problem is that it uses command calls, and I need to use this sub for 3-4 different viewports (for 'header', 'footer', 'side-legend', 'main-window') on like 100 layouts and the whole thing becomes very sloow... So right now I'm trying to figure out how to 'activate' that certain viewport, zoom to the BoundingBox, and 'deactivate' it, with ActiveX. BTW I've checked out this regarding viewport activation/deactivation, but unfortunately doesn't work for me (upon 'manual' testing). Quote
Jonathan Handojo Posted April 12, 2021 Posted April 12, 2021 I deal with this at my everyday work to generate printouts for hundreds of sections of detailed drawings, and I just cheated a small bit. The difference between you and me is, as opposed to 5-6 viewports, I only deal with one each layout. What I do to overcome this slowness at my workplace is have one "master" layout and copy that layout with a desired name. Using (command "_LAYCOPY") works a bit quicker for me. Then depending on the number of viewports in each layout, you can do (setvar 'cvport 2, 3, 4, ...) and then (vla-ZoomWindow <modelspace>). Finally, do (setvar 'cvport 1) [which I think does exactly (command "_pspace"). Point being, every certain viewport has its own number that you can get and set using (getvar 'cvport) and (setvar 'cvport <integer>) respectively. As far as I know, cvport of 1 is always the paperspace. Hopefully it helps out. 1 Quote
ronjonp Posted April 12, 2021 Posted April 12, 2021 (edited) You can also get the CVPORT value using DXF code 69 from the viewport entity. Nevermind see that @Grrr is already doing this . Edited April 12, 2021 by ronjonp Quote
Grrr Posted April 12, 2021 Author Posted April 12, 2021 (edited) 13 hours ago, Jonathan Handojo said: What I do to overcome this slowness at my workplace is have one "master" layout and copy that layout with a desired name. Using (command "_LAYCOPY") works a bit quicker for me. Then depending on the number of viewports in each layout, you can do (setvar 'cvport 2, 3, 4, ...) and then (vla-ZoomWindow <modelspace>). Your approach makes sense to me for coming-up with a faster algorithm by just zooming on the first layout instance and utilising the CopyObjects method: (defun test ( / SS->oL acDoc layouts lyt1 lyt2 oL ) (defun SS->oL ( SS / i L ) (if SS (repeat (setq i (sslength SS)) (setq L (cons (vlax-ename->vla-object (ssname SS (setq i (1- i)))) L)))) L) (setq layouts (vla-get-Layouts (setq acDoc (vla-get-ActiveDocument (vlax-get-acad-object))))) (setq lyt1 (vla-item layouts "Layout1")) (setq lyt2 (vla-item layouts "Layout2")) ; (list lyt1 lyt2) (setq oL (SS->oL (ssget "_X" (list (cons 410 "Layout1"))))) (vlax-invoke acDoc 'CopyObjects oL (vla-get-Block lyt2)) ); defun Still untested in my main routine, but I suspect NxTimes faster results. 13 hours ago, Jonathan Handojo said: Finally, do (setvar 'cvport 1) [which I think does exactly (command "_pspace"). Thanks, with your advice I might be able to get rid of the command calls of this sub. 2 hours ago, ronjonp said: You can also get the CVPORT value using DXF code 69 from the viewport entity. Nevermind see that @Grrr is already doing this . I mean, its basically rlx's code (I just modd-ed it a bit) "to suit my needs" However I don't get why the following errors out when I try to manually change the cvport system variable: (defun C:test ( / cvp vp enx ll ur ) (and (setq cvp (getvar 'cvport)) (setq vp (car (entsel "\nPick viewport: "))) (setq enx (entget vp)) (setvar 'cvport (cdr (assoc 69 enx))) ; Pick viewport: ; error: AutoCAD variable setting rejected: CVPORT 4 (vla-getBoundingBox (vlax-ename->vla-object (car (entsel "\nPick Object"))) 'll 'ur) (vla-ZoomWindow (vlax-get-acad-object) ll ur) (setvar 'cvport cvp) ); if ); defun Another annoying fact is that this ID, obtained thru (vports) for the viewport (dxf 69) is not contained as a property for the viewport object. Edited April 12, 2021 by Grrr Quote
ronjonp Posted April 12, 2021 Posted April 12, 2021 (edited) @Grrr Give this a try: (defun c:test (/ d cvp vp enx ll ur) (cond ((and (setq vp (car (entsel "\nPick viewport: "))) (setq enx (entget vp))) ;; Force model space before setting cvport (vlax-put (setq d (vla-get-activedocument (vlax-get-acad-object))) 'mspace 1) (setvar 'cvport (cdr (assoc 69 enx))) (vla-getboundingbox (vlax-ename->vla-object (car (entsel "\nPick Object"))) 'll 'ur) (vla-zoomwindow (vlax-get-acad-object) ll ur) (vlax-put d 'mspace 0) ) ;; (setvar 'cvport cvp) ) ; if ) ; defun Edited April 13, 2021 by ronjonp 2 Quote
Grrr Posted April 12, 2021 Author Posted April 12, 2021 16 minutes ago, ronjonp said: @Grrr Give this a try: Thanks @ronjonp, with this example I should certainly get rid of the command calls within my initial subroutine! Quote
ronjonp Posted April 13, 2021 Posted April 13, 2021 13 hours ago, Grrr said: Thanks @ronjonp, with this example I should certainly get rid of the command calls within my initial subroutine! Glad to help 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.