I would like to know the proper way of activating each viewport in each paper-space layout tab. I have some idea of the way to do this. And by and large, my code works. But I have encountered a very strange problem in my program (AutoCAD refuses to QUIT). And I trace the problem to the area in my program that activates each viewport in each paper-space layout tab. Of course there may be another cause of this problem. But before I go after the other possible cause of this problem, I need to be sure that my program is using the correct techique to activate each viewport in each paper-space layout tab. That's why I post my question here.
The following test-program is how my program activates each viewport in each paper-space layout tab:
(defun JayTest ( / oActiveDoc oCurLayout sCurLayoutName i ssVp entnameCurVp entdataCurVp nCurVpId oCurVpObj ) (setvar "CMDECHO" 0) (command "Tilemode" 1) (vl-load-com) ;Activate each viewport in each paper-space layout tab. (setq oActiveDoc (vla-get-activedocument (vlax-get-acad-object))) (vlax-for oCurLayout (vla-get-layouts oActiveDoc) (setq sCurLayoutName (vla-get-Name oCurLayout)) (if (not (eq sCurLayoutName "Model")) (progn ;Switch to the current paper-space layout tab. (setvar "CTab" sCurLayoutName) ;Select all viewports inside the current layout tab. (setq i -1) (if (setq ssVp (ssget "_X" (list (cons 0 "VIEWPORT" ) (cons 410 (getvar 'CTAB)) ) ) ) ;Loop through all the viewports one by one. (while (setq entnameCurVp (ssname ssVp (setq i (1+ i)))) ;Get the viewport ID. (setq entdataCurVp (entget entnameCurVp)) (setq nCurVpId (cdr (assoc 69 entdataCurVp))) ;Activate the viewport if it is not viewport-1. (if (> nCurVpId 1) (progn ;;;;;;;;;;;;QUESTION_AREA (command "ZOOM" "E") ;Zoom-extents to avoid the failure ; to activate some viewports that ; are off the screen. (command "_MSPACE") ;Switch to model space in order to ; activate viewports in the ; paper-space layout tab. ;;;;;;;;;;;;QUESTION_AREA ;Activate the viewport in order to get access to the ;pieces inside the viewport. (setvar "CVPORT" nCurVpId) ;Here, we are supposed to check the number of pieces ;inside the active viewport. But to simplify this test, ;we choose not to do anything. ;;;;;;;;;;;;QUESTION_AREA ;Go back to the paper-space mode. Otherwise, if we ;stayed in model space and when we did ZOOM above, we ;would have zoomed inside the model space of the ;viewport instead of zooming the view of the paper- ;space layout. (command "_PSPACE") ;;;;;;;;;;;;QUESTION_AREA ) ;progn ) ;if ) ;while ) ;if ) ;progn ) ;if ) ;vlax-for ;Switch back to model space. (setvar "CMDECHO" 0) (command "Tilemode" 1) (princ) )
As I said above, I trace the problem to this area shown above. And I also trace the problem to the specific statements (ZOOM-Extent, MSPACE, and PSPACE). That's why I have highlighted them above.
Please check to see if it is doing the right thing or not. If it is not, I will change that to see if the problem may go away. If it is doing the right thing, I will have to look elsewhere for the cause of my problem.
Please help. Thanks in advance.
Jay Chan
Solved! Go to Solution.
Solved by hmsilva. Go to Solution.
Hello
Sorry I am not at all a Lisp/VLisp progralmmer, so my remarks will be "stupid" maybe !?
With large DWG with many layouts and many viewports, the cost in memory (because of the Graphic Display List for each viewport) could be very high !
So have you tried to run with LAYOUTREGENCTL = 1 (Slow switching between each Layout) and not with the default value = 2 ?
Patrice BRAUD
I don't think memory is an issue because the computer still has plenty of memory left while it is processing the drawing. Anyway, I have tried LAYOUTREGENCTL in all three possible settings (0, 1, 2), and I still have the problem (AutoCAD cannot QUIT). Therefore, the problem has nothing to do with memory usage. At this point, I am quite sure the problem has to do with the third party software because I find that the problem goes away if the program unloads the third party software before it starts activating viewports.
Still, I would like to know if the way that I activate each viewport in each paper-space layout tab is correct or not. Any idea?
Jay Chan
As a demo
(defun c:demo (/ e_ctab nt i ss vp) (setq _ctab (getvar 'CTAB)) (foreach x (layoutlist) (setvar 'CTAB x) (command "_.zoom" "_E") (if (setq ss (ssget "_X" (list '(0 . "VIEWPORT") (cons 410 x)))) (repeat (setq i (sslength ss)) (setq ent (entget (ssname ss (setq i (1- i)))) vp (cdr (assoc 69 ent)) ) (if (> vp 1) (progn (command "_.mspace") (setvar 'CVPORT vp) (alert "Press OK to continue...") ) ) ) ) (command "_.pspace") ) (setvar 'CTAB _ctab) (princ) )
Henrique
No real idea what you are trying to do... but this was tested on other idiotic drawings (20+ tabs with 20+ vps each)
( defun c:VPREGEN ( / B_CTAB B_ITEM ) ( setvar "maxactvp" 64) ( setq B_CTAB ( getvar "CTAB" ) ) ( foreach B_ITEM ( layoutlist )
( setvar "CTAB" B_ITEM ) ( vla-regen ( vla-get-activedocument ( vlax-get-acad-object ) ) acAllViewports ) ) ( setvar "CTAB" B_CTAB ) ( princ ) )
( defun C:B_ZOOMEX ( / B_ACAD BSPACE B_CTAB ) ( setq B_ACAD ( vlax-get-acad-object ) ) ( setq B_CTAB ( getvar "CTAB" ) ) ( foreach B_ITEM ( layoutlist ) ( progn ( setvar "CTAB" B_ITEM ) ( vla-zoomextents B_ACAD ) ) ) ( setvar "CTAB" "Model" ) ( vla-zoomextents B_ACAD ) ( setvar "CTAB" B_CTAB ) ( princ ) )
Hi hmsilva!
Thanks for the sample code. I can see there are some differences between mine and yours, and the chance is good that yours is correct. I have incorporated your way of activating the viewports in my code, and now I am testing the program with multiple drawings. I will get back to you as soon as I am done with testing (probably late tomorrow morning).
Jay Chan
You're welcome, jchan,
change
(if (> vp 1) (progn (command "_.mspace") (setvar 'CVPORT vp) ;; to (if (> vp 1) (progn (if (not (and (= 0 (getvar "tilemode")) (>= (getvar "cvport") 2))) (command "_.mspace") ) (setvar 'CVPORT vp)
to not call the mspace command if a viewport is activated...
Henrique
Hi hmsilva:
Thanks for the sample code. I have learned two things from yours:
I have one question that I hope you (or other forum member) may be able to answer:
(vlax-for oCurLayout (vla-get-layouts oActiveDoc) . . (setvar "CTab" sCurLayoutName) (command "ZOOM" "E") (setq i -1) (if (setq ssVp (ssget "_X" (list (cons 0 "VIEWPORT" ) (cons 410 (getvar 'CTAB)) ) ) ) (while (setq entnameCurVp (ssname ssVp (setq i (1+ i)))) . . (if (> nCurVpId 1) (progn (command "_MSPACE") <-------| (setvar "CVPORT" nCurVpId) | . |-- A pair . Do something | . | (command "_PSPACE") <-------| ) ;progn ) ;if ) ;while ) ;if . . ) ;vlax-for
I have changed my program to follow the sample code. But I still have the problem of AutoCAD refuses to QUIT. I find that the problem must have to do with the third party software and not much to do with how I navigate through viewports. Therefore, the solution is to unload the third party software before I go through the viewports. This is my workaround for now until the third party software is fixed.
Hello for all other forum members that have posted your sample code:
Although I don't get to use your sample programs, I appreciate the fact that you have tried to help me. I am sure other people who come across this message thread in the future will help your sample programs to be useful. Thanks.
Jay Chan
You're welcome, Jay Chan
You can write the code as you described, but notices notices the MSPACE/PSPACE command will be called once for each viewport, whereas in my 'demo' the MSPACE/PSPACE command will be called once for each layout.
Henrique
Thanks for pointing out that pairing MSPACE and PSPACE as what I suggested would end up calling PSPACE for every viewport. That would be a total waste of time.
I appreciate your help.
Jay Chan
HMSILVA,
I discoverd your code in the Autolisp forum while I was looking for something a bit different.
After running the code, I see that it will cycle through all viewports in the drawing (skippling Layout Tabs that have no Viewports).
May I ask if it is possible to modify so that the code will also stop at any Layout that has no Viewport ?
The reason I ask, is that I am trying to prepare a lisp which will cycle through all Layouts and Viewports and save the current Layerstate of each.
The LayerState would be named on the "Layout Name" where there are no Viewports OR the "Layout Name: VP X" where X would be the Vport number.
If you would be so kind modify the lisp to stop at a Layout Tab with no viewport, I think I could then finish the code to save the layer state.
Any assistance would be appreciated.
(defun c:demo (/ e_ctab nt i ss vp)
(setq _ctab (getvar 'CTAB))
(foreach x (layoutlist)
(setvar 'CTAB x)
(command "_.zoom" "_E")
(if (setq ss (ssget "_X" (list '(0 . "VIEWPORT") (cons 410 x))))
(repeat (setq i (sslength ss))
(setq ent (entget (ssname ss (setq i (1- i))))
vp (cdr (assoc 69 ent))
)
(if (> vp 1)
(progn
(if (not (and (= 0 (getvar "tilemode")) (>= (getvar "cvport") 2)))
(command "_.mspace")
)
(setvar 'CVPORT vp)
(alert "Press OK to continue...")
)
)
)
)
(command "_.pspace")
)
(setvar 'CTAB _ctab)
(princ)
)
This?
(defun c:demo (/ _ctab layst nt i ss vp) (setq _ctab (getvar 'CTAB)) (foreach x (layoutlist) (setvar 'CTAB x) (if (and (= 0 (getvar "tilemode")) (>= (getvar "cvport") 2)) (command "_.pspace") ) (command "_.zoom" "_E") (alert (strcat "Do " x " Layerstate stuff... ")) (if (setq ss (ssget "_X" (list '(0 . "VIEWPORT") '(-4 . "!=") '(69 . 1) (cons 410 x)))) (repeat (setq i (sslength ss)) (setq hnd (ssname ss (setq i (1- i))) ent (entget hnd) vp (cdr (assoc 69 ent)) ) (if (> vp 1) (progn (if (not (and (= 0 (getvar "tilemode")) (>= (getvar "cvport") 2))) (command "_.mspace") ) (setvar 'CVPORT vp) (setq layst (strcat x ": VP " (itoa vp))) (alert (strcat "Do " layst " Layerstate stuff... ")) ) ) ) ) (command "_.pspace") ) (setvar 'CTAB _ctab) (princ) )
Hope this helps,
Henrique