The vla-RefreshPlotDeviceInfo function modifies the layout settings

The vla-RefreshPlotDeviceInfo function modifies the layout settings

cbujor
Participant Participant
1,891 Views
24 Replies
Message 1 of 25

The vla-RefreshPlotDeviceInfo function modifies the layout settings

cbujor
Participant
Participant

For some plots, probably those that have the insertion units in inches or others other than metric, when the units of measurement of the plot settings are in millimeters and the vla-RefreshPlotDeviceInfo function is applied these units are changed to inches and the layout is changed.

Normally, the vla-RefreshPlotDeviceInfo function should not make any changes to the layout for which it is being refreshed.

I solved the problem by copying the active layout into a temporary layout, then I applied this function, after which I deleted the temporary layout. I'm not sure if this works, that is, if the vla-RefreshPlotDeviceInfo function took the information from the temporary layout and these are used in the active layout.

0 Likes
Accepted solutions (1)
1,892 Views
24 Replies
Replies (24)
Message 2 of 25

Moshe-A
Mentor
Mentor

@cbujor  hi,

 

Unfortunatley you are right, i also notice that there are bugs in Plot Configuration \ Layout objects and the way to deal with it is by been aware of it and do exactly what you did, save the property, use vla-RefreshPlotDeviceInfo, restore the property - that's it 🤣

 

Moshe

 

0 Likes
Message 3 of 25

cbujor
Participant
Participant

Is there another possibility to save the properties of a layout and then restore them without using the -LAYOUT command?

Using the -LAYOUT command I have to create a temporary layout by copying and then deleting it, which is not very elegant.

0 Likes
Message 4 of 25

Moshe-A
Mentor
Mentor

@cbujor hi,

 

this command copies the layout1 settings to layout2 😀

 

Moshe

 

 

(defun c:test (/ AcDbLayouts AcDbLayout AcDbLayout2)

 (setq AcDbLayouts (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))))

 (setq AcDbLayout1 (vla-item AcDbLayouts "layout1")) 
 (setq AcDbLayout2 (vla-item AcDbLayouts "layout2")) 

 (vla-copyFrom AcDbLayout2 AcDbLayout1)
   
 (princ)
)

 

0 Likes
Message 5 of 25

cbujor
Participant
Participant

Your proposal is similar to using the -LAYOUT command.
Is it possible to keep the layout properties without creating a second layout?

1. I save the properties of the current layout in an object;

2, Apply the vla-RefreshPlotDeviceInfo function that will change the layout properties;
3. Restore the properties of the current layout.

0 Likes
Message 6 of 25

Moshe-A
Mentor
Mentor

@cbujor 

 

You are right my apologize

in that case you will have to do it 'manually', construct a list with all the relevant properties.

 

Moshe

 

 

0 Likes
Message 7 of 25

cbujor
Participant
Participant

My approach was the following:

 

(defun GetLayout (LayoutName / Obj)
 (if (= 'vla-object (type (setq Obj (vl-catch-all-apply 'vla-item (list (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) LayoutName)))))
  Obj
 )
)

(setq LayoutTemp "TEMP_LAYOUT_")
(command "._-LAYOUT" "_C" LayoutName LayoutTemp)
(setq LayoutObj (GetLayout LayoutTemp))
(if LayoutObj
 (progn
  (vla-RefreshPlotDeviceInfo LayoutObj)
  (command "._-LAYOUT" "_D" LayoutTemp)
 )
)

 

Is there a possibility to solve this problem without creating the "TEMP_LAYOUT_" layout?

 

0 Likes
Message 8 of 25

Moshe-A
Mentor
Mentor

@cbujor ,

 

Here is your solution, the only drawback is four properties that we can not modify (vla-put-property...)

check PlotConfiguration object (they are similar) maybe you'll get more luck 😀

 

enjoy

Moshe

 

 

(defun save_layout_settings (AcDbLayout properties^)
 (mapcar
   (function
     (lambda (prop)
      (eval (list (eval (read (strcat "vla-get-" prop))) AcDbLayout))
     )
   )
  properties^ 
 )
); save_layout_settings


(defun restore_layout_settings (AcDbLayout properties^ values^)
 (mapcar
   (function
     (lambda (prop val)
      (if (null (member prop '("CanonicalMediaName" "centerPlot" "modelType" "ViewToPlot")))
       (eval (list (eval (read (strcat "vla-put-" prop))) AcDbLayout val))
      )
     )
   )
  properties^ values^ 
 )
); restore_layout_settings


(defun c:test (/ properties^ values^ AcDbLayouts AcDbLayout1)

 (setq properties^ '("CanonicalMediaName" "centerPlot" "configName" "modelType" "name"
		     "paperunits" "plotHidden" "plotOrigin" "plotRotation" "plotType"
		     "PlotViewportBorders" "PlotViewportsFirst" "PlotWithLineweights"
		     "PlotWithPlotStyles" "ScaleLineweights" "ShowPlotStyles" "StandardScale"
		     "StyleSheet" "TabOrder" "UseStandardScale" "ViewToPlot"))
  
 (setq AcDbLayouts (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))))
 (setq AcDbLayout1 (vla-item AcDblayouts "Layout1"))

 (setq values^ (save_layout_settings AcDbLayout1 properties^))
 (restore_layout_settings AcDbLayout1 properties^ values^)
 
 (vlax-release-object AcDbLayout1)
 (vlax-release-object AcDbLayouts)

 (princ "\nDone.")
)

 

 

0 Likes
Message 9 of 25

cbujor
Participant
Participant

It is a complicated solution and I don't know if some of the properties of the layout are omitted.
Anyway, thanks for your effort. In your solution there are some things that I did not know about the capabilities of Visual Lisp.

0 Likes
Message 10 of 25

Moshe-A
Mentor
Mentor

@cbujor ,

 


@cbujor wrote:

It is a complicated solution and I don't know if some of the properties of the layout are omitted.

what do you mean by that, i took all the property from the manual
Anyway, thanks for your effort. In your solution there are some things that I did not know about the capabilities of Visual Lisp.

i'll be glade to clarify it for you 😀

 

you should focus only on the properties that matters you and ignore the rest 


 

0 Likes
Message 11 of 25

ec-cad
Collaborator
Collaborator

I may be way off, but I was wondering if an undo-begin / undo-end might put those Layouts back

to where they were... per:

(vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
and your changes here...
(vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))

 

ECCAD

0 Likes
Message 12 of 25

Moshe-A
Mentor
Mentor

@cbujor  Good morning,

 

Do not enter into despair 😀, we here to help solve this 🙏

maybe now is the time to tell us more about what you are trying to accomplish?!

 

At start you want to save layout settings (detail what specific properties is matter)

......

Your doing something in between - what's that?

......

At end restore layout setting.

 

if you already have a code, post it if you can?!

 

Moshe

 

0 Likes
Message 13 of 25

cbujor
Participant
Participant

I want to check if the plot style table exists?

(defun GetActLay ()
 (vla-get-ActiveLayout (vla-get-activedocument (vlax-get-acad-object)))
)

(defun GetLayout (LayoutName / Obj)
 (if (= 'vla-object (type (setq Obj (vl-catch-all-apply 'vla-item (list (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object))) LayoutName)))))
  Obj
 )
)

(defun RefreshPlotDeviceInfo (LayoutObj / LayoutName LayoutTemp)
 (if LayoutObj
  (progn
   (setq LayoutName (vla-get-name LayoutObj))
   (if (/= (strcase LayoutName) "MODEL")
    (progn
     (setq LayoutTemp "TEMP_LAYOUT_")
     (command "._-LAYOUT" "_C" LayoutName LayoutTemp)
     (setq LayoutObj (GetLayout LayoutTemp))
     (if LayoutObj
      (progn
       (vla-RefreshPlotDeviceInfo LayoutObj)
       (command "._-LAYOUT" "_D" LayoutTemp)
      )
     )
    )
    (vla-RefreshPlotDeviceInfo LayoutObj)
   )
  )
 )
)

(defun GetActivePlotStyleTable ()
 (vla-get-stylesheet (GetActLay))
)

(defun GetPlotStyleTableNamesList ()
 (RefreshPlotDeviceInfo (GetActLay))
 (vlax-safearray->list (vlax-variant-value (vla-GetPlotStyleTableNames (GetActLay))))
)

(defun PlotStyleTableExists (PlotStyleTableName / LstTableNames)
 (setq LstTableNames (GetPlotStyleTableNamesList))
 (or (= PlotStyleTableName "")
     (/= (member (strcase PlotStyleTableName) (mapcar '(lambda (Value) (strcase Value)) LstTableNames)) nil))
)

;This is the test
(setq hasErr1 (not (PlotStyleTableExists (GetActivePlotStyleTable))))
(princ "\n hasErr1=")(princ hasErr1)

(setq hasErr2 (not (PlotStyleTableExists "non-existent.ctb")))
(princ "\n hasErr2=")(princ hasErr2)

(princ)
0 Likes
Message 14 of 25

Moshe-A
Mentor
Mentor

@cbujor hi,

 

here is my version and i used some of your functions

 

Moshe

 

 

 

 

(defun c:test (/ GetActLay GetPlotStyleTableNamesList isexist ; local functions
	         AcDbLayout plotStyleTableList activePlotStyleTableName)

 (defun GetActLay ()
  (vla-get-ActiveLayout (vla-get-activedocument (vlax-get-acad-object)))
 )
   
 (defun GetPlotStyleTableNamesList (AcDbLayout)
  (vla-RefreshPlotDeviceInfo AcDbLayout) 
  (vlax-safearray->list (vlax-variant-value (vla-GetPlotStyleTableNames AcDbLayout)))
 ); GetPlotStyleTableNamesList 


 (defun isexist (/ psname)
  (vl-some
   (function
    (lambda (psname)
     (if (eq psname activePlotStyleTableName) psname)
    )
   )
   (mapcar (function (lambda (name) (strcase name))) (GetPlotStyleTableNamesList AcDbLayout))
  ) 
 ); isexist
  
  
 (setq AcDbLayout (GetActLay))
 (setq plotStyleTableList (GetPlotStyleTableNamesList AcDbLayout))
 (setq activePlotStyleTableName (strcase (vla-get-stylesheet AcDbLayout)))

 (if (isexist)
  (princ "\nfound")
  (princ "\nnot found")
 )

 (vlax-release-object AcDbLayout) 

 (princ)
); c:test  

 

 

0 Likes
Message 15 of 25

cbujor
Participant
Participant

I used the RefreshPlotDeviceInfo function created by me and you used vla-RefreshPlotDeviceInfo which produces the effect described in this topic.
In my example, the operation is correct. The problem is that I had to create a copy of the current layout. If there was a simple solution to save a layout without copying, then I would be satisfied.

0 Likes
Message 16 of 25

cbujor
Participant
Participant

I cannot apply this solution because a process for undo begin - undo end for several operations is already started.

0 Likes
Message 17 of 25

Moshe-A
Mentor
Mentor

@cbujor ,

 

i pretty sure this can be solved without creating layout but you did not tell me what are the properties that are matter to you except for the plot style table name.

 

your (RefreshPlotDeviceInfo) function only creates a layout, no saving setting i can see, as i remember you want to save layout settings and at end restore?

 

Moshe

 

 

0 Likes
Message 18 of 25

cbujor
Participant
Participant

Before printing if the plot style table exists to avoid a printing error. I also check if the print driver exists, also to avoid the printing errors that the -PLOT command will display.

To do this check, it is imperative to use the vla-RefreshPlotDeviceInfo function, which changes the print scale from the current layout.

If I do not return to the initial layout, then the printing result is wrong.

0 Likes
Message 19 of 25

Moshe-A
Mentor
Mentor

@cbujor ,

 


@cbujor wrote:

I used the RefreshPlotDeviceInfo function created by me and you used vla-RefreshPlotDeviceInfo which produces the effect described in this topic.
In my example, the operation is correct. The problem is that I had to create a copy of the current layout. If there was a simple solution to save a layout without copying, then I would be satisfied.


Maybe i still do not understand you, what do you mean by "save a layout" without creating one?

a layout (or any other object) is a bunch of properties (yes and methods\functions) by saving these properties (say to a list) you saved the layout in AutoLISP memory - sounds logic?

 

Moshe

 

 

 

 

 

0 Likes
Message 20 of 25

cbujor
Participant
Participant

Perhaps a simpler description of this problem would be for the vla-RefreshPlotDeviceInfo function to be rewritten so that the layout to which it is applied to remains unchanged.

0 Likes