Jump to content

Zoom From Viewport via ActiveX


Grrr

Recommended Posts

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).

 

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

You can also get the CVPORT value using DXF code 69 from the viewport entity.

Nevermind see that @Grrr is already doing this :)

.

Edited by ronjonp
Link to comment
Share on other sites

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" :lol:

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 by Grrr
Link to comment
Share on other sites

@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 by ronjonp
  • Like 2
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...