fastest way to create layout and viewport

fastest way to create layout and viewport

Anonymous
Not applicable
3,483 Views
11 Replies
Message 1 of 12

fastest way to create layout and viewport

Anonymous
Not applicable

Hi all,

 

In my code I need to make a hundreds of layouts.

Right now I'm using next method to do this.

 

1. make a copy of layout example:

(vl-cmdf "_.layout" "copy" laytocopy cur-layout-name)

2. activate new layout:

(vla-put-activelayout acdoc  (vla-item vla-layouts cur-layout-name))

3. make new vieport:

(vl-cmdf "_.mview" "_NONE" p1 "_NONE" p2)
(setq vp (vlax-ename->vla-object (entlast)))
(vla-Display vp :vlax-true)

4. set viewport properties:

(vla-put-twistangle vp twist)

 

(vla-put-displaylocked vp :vlax-false)

 

(vla-put-mspace acdoc :vlax-true)

 

(vla-put-activepviewport acdoc vp)

 

(vlax-invoke acad 'ZoomCenter center 1.0)

 

(vla-put-CustomScale vp vp-scale)

 

(vla-put-mspace acdoc :vlax-false)

 

This is the method which I'm using, but sometimes it is too slow...

 

Is there any faster way to do this?

 

Thank you for answers,

dicra

 

 

 

 

 

 

0 Likes
3,484 Views
11 Replies
Replies (11)
Message 2 of 12

hmsilva
Mentor
Mentor

@Anonymous wrote:

...

In my code I need to make a hundreds of layouts.

Right now I'm using next method to do this.

 

1. make a copy of layout example:

(vl-cmdf "_.layout" "copy" laytocopy cur-layout-name)

2. activate new layout:

(vla-put-activelayout acdoc  (vla-item vla-layouts cur-layout-name))

3. make new vieport:

(vl-cmdf "_.mview" "_NONE" p1 "_NONE" p2)
...

This is the method which I'm using, but sometimes it is too slow... 

Is there any faster way to do this?


Hi dicra,

some doubts..

 

Are you going to create 'hundreds of layouts' in one dwg?

Using '(vl-cmdf "_.layout" "copy" laytocopy cur-layout-name)' several hundred times and adding a new viewport each time, you'll have a huge number of viewports, that's what you need to do?

 

Henrique

EESignature

0 Likes
Message 3 of 12

Anonymous
Not applicable
Henrique,

Thank you for interesting in my problem.
This is exactly what I'm trying to do.

First, I was thinking to find the way to make layout and viewport with out activating any of them, but I think it is not possible to change properties of viewport with out activating.

dicra
0 Likes
Message 4 of 12

hmsilva
Mentor
Mentor

May be faster...

Quick and dirty, as a starting point

 

(defun c:demo (/ acdoc blks center cur-layout-name curr height laytocopy new twist vla-layouts vp vp-scale width)

  (or *acad (setq *acad (vlax-get-acad-object)))
  (setq acdoc (vla-get-ActiveDocument *acad))

  (setq cur-layout-name  "test002"
        laytocopy "Layout1"
        blks nil
        twist 0.0
        vp-scale acVp1_1
  )

  (setq vla-layouts (vla-get-layouts acdoc))
  (vla-put-activelayout acdoc (vla-item vla-layouts laytocopy))

  (setq curr (vla-item vla-layouts (getvar 'ctab)))
  (setq new (vla-add vla-layouts cur-layout-name))
  (vla-put-ActiveLayout acdoc new)
  (setq center (vlax-3d-point 3 3 0)
        width  40
        height 40
  )
  (setq vp (vla-AddPViewport
             (vla-get-PaperSpace acdoc)
             center
             width
             height
           )
  )
  (vla-copyfrom new curr)
  (vlax-for blk (vla-get-block curr)
    (if (/= (vla-get-objectname blk) "AcDbViewport")
      (setq blks (cons blk blks))
    )
  )

  (if blks
    (progn
      (setq blks (reverse blks))
      (vlax-invoke acdoc 'CopyObjects blks (vla-get-block new))
    )
  )

  (vla-Display vp :vlax-true)
  (vla-put-twistangle vp twist)
  (vla-put-displaylocked vp :vlax-false)
  (vla-put-mspace acdoc :vlax-true)
  (vla-put-activepviewport acdoc vp)
  (vla-ZoomCenter *acad center 1.0)
  (vla-put-CustomScale vp vp-scale)
  (vla-put-mspace acdoc :vlax-false)
  (vlax-Release-Object vp)
  (vla-Regen acdoc acActiveViewport)
  (princ)
)

 

Hope that helps

Henrique

EESignature

0 Likes
Message 5 of 12

Anonymous
Not applicable

Henrique,

 

It looks like your method is faster, time is shorter for about 25 %.

Using vla-add for making new layout, and invoking 'CopyObjects is faster than autocad vl-cmdf "_.layout" "copy".

I made test on acad 2012, later I will do the same on acad 2014.

 

Maybe the reasson why your method is quicker is because you made filter for copying viewports in example layout.

I will test that too.

 

Thank you very much for your help, I'm learning a lot from your codes.

 

Even if it is a lot more faster whit your method, I will still try to fast up my code.

I was hopping that there is a method to create a new layout and viewport, whit out activating them. This activations, and changes from one layout to another are really slow. After spending a lot of time on search for other methods, I found out that it is not possible to use entmake on viewport, or to change viewport in dictionary.

Is it possible to do that by using ARX or .NET?

 

dicra

 

 

 

0 Likes
Message 6 of 12

hmsilva
Mentor
Mentor

You're welcome, dicra!

 

In my previous 'quick' demo, I did remove the 'viewport' objects from the copy, because I had no time to write an 'acceptable' code...

As a 'demo' and not tested (I don't have AutoCAD in this laptop)

 

(defun c:demo (/ acdoc blks center cur-layout-name curr height laytocopy new twist vla-layouts vp vpm vp-scale width)
  (or *acad (setq *acad (vlax-get-acad-object)))
  (setq vpm (getenv "CreateViewports"))
  (setenv "CreateViewports" "0")
  (setq acdoc           (vla-get-ActiveDocument *acad)
        cur-layout-name "test003"
        laytocopy       "Layout1"
        blks            nil
        twist           0.0
        vp-scale        acVp1_1
        vla-layouts     (vla-get-layouts acdoc)
        curr            (vla-item vla-layouts laytocopy)
        new             (vla-add vla-layouts cur-layout-name)
  )
  (vla-put-ActiveLayout acdoc new)
  (setq center (vlax-3d-point 3 3 0)
        width  40
        height 40
	vp (vla-AddPViewport (vla-get-PaperSpace acdoc) center width height)
) (vla-copyfrom new curr) (vlax-for blk (vla-get-block curr) (setq blks (cons blk blks))) (if (and blks (> (length blks) 1) ) (progn (setq blks (reverse blks)) (setq blks (cdr blks)) (vlax-invoke acdoc 'CopyObjects blks (vla-get-block new)) ) ) (vla-Display vp :vlax-true) (vla-put-twistangle vp twist) (vla-put-displaylocked vp :vlax-false) (vla-put-mspace acdoc :vlax-true) (vla-put-activepviewport acdoc vp) (vla-ZoomCenter *acad center 1.0) (vla-put-CustomScale vp vp-scale) (vla-put-mspace acdoc :vlax-false) (vlax-Release-Object vp) (vla-Regen acdoc acActiveViewport) (setenv "CreateViewports" vpm) (princ) )

 

Copying the viewports from the source layout, and should be faster than the previous one, because it don't set as current the source layout.

 

'I think' it will not be possible to create a layout and viewport, whit out activating, because, to initialize a layout we'll nead to making it current.

Hopefully, someone else will point us the right way.

 

Hope that helps
Henrique

EESignature

Message 7 of 12

Anonymous
Not applicable

Henrique,

 

I just wanted to ask is it possible to prevent creation of new viewport when creating layout, and you already made that change.

(setenv "CreateViewports" "0") is reducing the time a lot.

 

There are few things which I changed when I'm using your code.

I'm repeating process of layout coping, so I don't need to repeat 

(vlax-for blk (vla-get-block curr) (setq blks (cons blk blks))) ,

for every layout which I'm creating. I need it only once, and later I can use it for every 

 

Second thing is that, for every layout, I need to make new viewprot, because every viewport is having different dimensions.

When making new viewport, it is necessary to use, for example (vl-cmdf "_.zoom" "_extents"), before using (vla-put-mspace acdoc :vlax-true), because if viewport is not seen in current view, it is not possible to enter in viewport model space.

 

I manage to reduce time, by freezing all layers, too. Time was decreased significantly.

 

With all changes time was reduced a lot, Thank you for help.

 

I will work a bit more on this problem...

 

dicra

 

 

0 Likes
Message 8 of 12

hmsilva
Mentor
Mentor

@Anonymous wrote:

... for every layout, I need to make new viewprot, because every viewport is having different dimensions.

When making new viewport, it is necessary to use, for example (vl-cmdf "_.zoom" "_extents"), before using (vla-put-mspace acdoc :vlax-true), because if viewport is not seen in current view, it is not possible to enter in viewport model space.

...


Hi dicra,

 

why not

 

(vla-ZoomExtents *acad)

 

instead of vl-cmdf "_.zoom" ...

 

Henrique

EESignature

0 Likes
Message 9 of 12

r.schlich
Contributor
Contributor

Hey enrique,

 

thank you for your awesome example!

 

Sorry to revive an ancient thread, but i've been looking for an example to copy layouts and create new viewports with lisp for some time now, and your example is basically answering (almost) all of my questions at once. There's just one little thing i don't understand.

 

This block of code

  (vlax-for blk (vla-get-block curr) (setq blks (cons blk blks)))
  (if 
    (and blks 
         (> (length blks) 1)
    )
    (progn 
      (setq blks (reverse blks))
      (setq blks (cdr blks))
      (vlax-invoke acdoc 'CopyObjects blks (vla-get-block new))
    )
  )

creates a list of all entities on the layout to be copied, but before copying each entity to the new layout you reverse the list and skip the first (which was originally the last) element of that list.

 

What does the last element of a block contain to make you go to such "lengths" to not copy it?

 

Looking forward to your answer and once again thank you for your code!!! 😁

0 Likes
Message 10 of 12

hmsilva
Mentor
Mentor

@r.schlich 

building the list using

(vlax-for blk (vla-get-block curr) (setq blks (cons blk blks)))

the first block becomes the last element of the list, reversing the list, it becomes the first element, using cdr removes it.

The first block is the layout...

 

Hope this helps,
Henrique

 

EESignature

Message 11 of 12

r.schlich
Contributor
Contributor

Awesome! Thank you for your fast response!

 

So putting together what i already knew and what you just told me i'm getting the following picture of how a layout works:

- A Layout of a DWG file is basically just a block which's IsLayout Property is true

- The first element of said block is the Layout object which contains the information about plotstyle, papersize etc.

- To create a new Viewport in a layout:

  1.  the layout first needs to be activated in our acdoc object via vla-put-ActiveLayout
  2. then we can add a Viewport to the PaperSpace of our Active Document or acdoc objekt via vla-AddPViewport
  3. the PaperSpace is accessed via vla-get-PaperSpace and allways revers to the activated Layout which is why we need to activate the layout prior to adding the viewport in the first place

- Orientation of the viewport can be changed anytime using vla-put-twistangle

- to change the ModellExtends, the viewport shows:

  1. the viewport needs to be unlock via vla-put-displaylocked
  2. ModellSpace has to be activated using vla-put-mspace
  3. the viewport hast to be made the active viewport using vla-put-activeviewport
  4. the viewport can then be changed using vla-ZoomCenter or / and vla-put-CustomScale
  5. the viewport can then be locked again and autocad can be switched back to paperspace

Wew, it would have taken me ages, to figure all this out by myself. Realy a great code example! Thanks again.

 

Side question:

What does vlax-Releas-Object do to the viewport?

0 Likes
Message 12 of 12

Sea-Haven
Mentor
Mentor

Do you want the layouts to be auto created based on rectangs in Model ? If so can match your title block etc be created with a scale set, the rectangs can be moved, copied and rotated then layouts created. The rotated view is reflected in the layouts. A small fee as needs to be customised to suit your title block.

 

SeaHaven_0-1687479796947.png

This image shows follow a pline, another is place multiple rectangs.

 

0 Likes