Delete empty viewports

Delete empty viewports

LeoManu
Enthusiast Enthusiast
747 Views
12 Replies
Message 1 of 13

Delete empty viewports

LeoManu
Enthusiast
Enthusiast

Hi, I’m trying to make a routine that deletes viewports in paper space that don’t show anything, they point to an empty part of model space. These empty viewports are often on top of the real ones that I need. Both are active, so it’s hard to tell which is which. I just want to clean the first layout because I need to run this in many drawings with a script.

 

Is it possible to do something like this? Thanks.

0 Likes
Accepted solutions (2)
748 Views
12 Replies
Replies (12)
Message 2 of 13

Moshe-A
Mentor
Mentor

@LeoManu  hi,

 

yes it can be done and here is my advice:

 

1. loop through layouts.

2. in layout trace the viewport create a pline put it on $temp layer (or use unusual color)

3. use chspace command to send it down to model space.

4. switch to model space.

5. (ssget) ; featch the pline on $temp layer, extract it's corners p1 + p2

6. use (ssget "w" p1 p2)

    if noting found - it's empty 😀

 

enjoy,

Moshe

 

0 Likes
Message 3 of 13

john.uhden
Mentor
Mentor

@Moshe-A ,

Very astute, except that viewports can polygonal, but "WP" can take care of that.

I am more interested if any of the MSpace objects are on frozen layers.  Do they count?

John F. Uhden

0 Likes
Message 4 of 13

Sea-Haven
Mentor
Mentor

@Moshe-A you can get the co-ordinates of a viewport, then can use a trans function to work out Model points. I use this to do a grid over a Viewport including if a Twist exists in the viewport. Start with this.

(if (= (vla-get-objectname obj)  "AcDbViewport")
(progn
(setq cen (vlax-get obj 'Center ))
(setq ht (vlax-get obj 'Height))
(setq wid  (vlax-get obj 'Width))
(setq sc (vlax-get obj 'customscale ))
(setq ang (vlax-get obj 'TwistAngle))
(setq xmin  (- (car cen)(/ wid 2.0)))
(setq xmax  (+ (car cen)(/ wid 2.0)))
(setq ymin  (- (cadr cen)(/ ht 2.0)))
(setq ymax  (+ (cadr cen)(/ ht 2.0)))

 

0 Likes
Message 5 of 13

paullimapa
Mentor
Mentor

Lee Mac has a nice program that takes a vport in layout and creates a pline in model:

Viewport Outline | Lee Mac Programming


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 6 of 13

Moshe-A
Mentor
Mentor

Guys,

 

thank you all for correcting me with all your good advices (mine was only a quick work flow before bed)

 

i am now have a feeling that a spirit of ESC (Eurovision Song Contest) host coming down to me  😀

so i say: "Start coding World"...

 

have a nice day

Moshe

 

0 Likes
Message 7 of 13

Kent1Cooper
Consultant
Consultant

@john.uhden wrote:

.... viewports can polygonal, but "WP" can take care of that.....


They can also be made from Polylines which can include arc segments.  In such a case, using the vertices in a WP selection will have all the same problems it causes in other kinds of usages.  Depending on the directions of curvature, it can miss seeing things that you want it to see, and it can see things you don't want it to see.

And they can even be made from full Ellipses and closed Splines, in which vertices and WP are completely out of the picture.

If you ever use Viewports like those, WP selection based on the vertices would not be a reliable [nor in some cases possible] way to determine whether a Viewport is empty.  You could get closer with the approach used in some other applications -- calculate a bunch of intermediate points along curves so a WP of lots of short straight segments at least more closely approaches the shape.

Kent Cooper, AIA
0 Likes
Message 8 of 13

LeoManu
Enthusiast
Enthusiast

For this case, all my viewports are rectangular and the objects inside are not locked or frozen, so a WP selection is enough. If a viewport has the model rotated, the corner points might get swapped, but for practical purposes, it will still work.

0 Likes
Message 9 of 13

Sea-Haven
Mentor
Mentor

For rectangular viewports even with a twist using the 4 corners and a trans will return the 4 points in a rotated sense. 

 

Yes Lee's code takes into account a rotation so would use that.

0 Likes
Message 10 of 13

LeoManu
Enthusiast
Enthusiast

Hi, I made this code but I don’t get why it deletes both viewports. I think the MSPACE command always goes to the same one. I’m kinda lost on what to do next.

(defun c:CleanEmptyVP (/ ssvp i vpEnt vpObj vpPts p1 p2 ssC)
  (vl-load-com)
  (defun getViewportModelRect (vport / obj cen ht wid xmin xmax ymin ymax p1 p2)
    (setq obj (vlax-ename->vla-object vport))
    (if (= (vla-get-ObjectName obj) "AcDbViewport")
      (progn
        (setq cen (vlax-get obj 'Center))
        (setq ht  (vlax-get obj 'Height))
        (setq wid (vlax-get obj 'Width))
        (setq xmin (- (car cen) (/ wid 2.0)))
        (setq xmax (+ (car cen) (/ wid 2.0)))
        (setq ymin (- (cadr cen) (/ ht 2.0)))
        (setq ymax (+ (cadr cen) (/ ht 2.0)))
        (setq p1 (trans (list xmin ymin 0.0) 3 2))
        (setq p2 (trans (list xmax ymax 0.0) 3 2))
        (list p1 p2)
      )
    )
  )
  (setvar "tilemode" 0)
  (command "_.Layer" "_S" "0" "")
  (command "_.Pspace")
  (setq ssvp (ssget "_X" (list '(0 . "VIEWPORT") '(-4 . ">") '(69 . 1) (cons 410 (getvar "ctab")))))
  (if ssvp
    (progn
      (setq i 0)
      (while (< i (sslength ssvp))
        (setq vpEnt (ssname ssvp i))
        (setq vpObj (vlax-ename->vla-object vpEnt))
        (if (= (vla-get-ObjectName vpObj) "AcDbViewport")
          (progn
            (vla-display vpObj :vlax-true)
            (vla-put-DisplayLocked vpObj :vlax-false)
            (setq vpPts (getViewportModelRect vpEnt))
            (setq p1 (car vpPts))
            (setq p2 (cadr vpPts))
            (command "_.MSPACE")
            (command "_.Zoom" ".9x")
            (setq ssC (ssget "_C" p1 p2))
            (command "_.Zoom" "_P")
            (command "_.PSPACE")
            (if (not ssC)
              (progn
                (entdel vpEnt)
              )
            )
          )
        )
        (setq i (1+ i))
      )
    )
  )
  (princ)
)

 

0 Likes
Message 11 of 13

paullimapa
Mentor
Mentor
Accepted solution

The main issue is the getViewportModelRect function should be run while inside the vport and not in pspace.

So I made the following changes:

1) localized getViewportModelRect

(defun c:CleanEmptyVP 
  (/ getViewportModelRect doc ssvp i lyrObj vpEnt vpnum vpObj vpPts p1 p2 ssC) ; localize functions & variables
  (vl-load-com)
  (defun getViewportModelRect (vport / obj cen ht wid xmin xmax ymin ymax p1 p2)
    (setq obj (vlax-ename->vla-object vport))
    (if (= (vla-get-ObjectName obj) "AcDbViewport")
      (progn
        (setq cen (vlax-get obj 'Center))
        (setq ht  (vlax-get obj 'Height))
        (setq wid (vlax-get obj 'Width))
        (setq xmin (- (car cen) (/ wid 2.0)))
        (setq xmax (+ (car cen) (/ wid 2.0)))
        (setq ymin (- (cadr cen) (/ ht 2.0)))
        (setq ymax (+ (cadr cen) (/ ht 2.0)))
        (setq p1 (trans (list xmin ymin 0.0) 3 2))
        (setq p2 (trans (list xmax ymax 0.0) 3 2))
        ; add the following lines of code
        (setq p1 (trans p1 2 0))
        (setq p2 (trans p2 2 0))
        ;
        (list p1 p2)
      )
    )
  )

2) get current dwg doc obj to make it easier to process other functions like regen and layer table

      (setq i 0
            doc (vla-get-activedocument (vlax-get-acad-object)) ; current active dwg
      )

3) Get vport number so can set correct vport in mspace

        (setq vpEnt (ssname ssvp i))
        (setq vpnum (getpropertyvalue vpEnt "number")) ; get vport number to use with cvport
        (setq vpObj (vlax-ename->vla-object vpEnt))

4) make sure layer is unlocked so vport can be erased:

        (if (= (vla-get-ObjectName vpObj) "AcDbViewport")
          (progn
            (setq lyrObj (vla-item (vla-get-layers doc) (vla-get-layer vpObj))) ; get layer object vport currently is on
            (vla-put-lock lyrobj :vlax-false) ; make sure layer object is unlocked

5) Place get vport corner function here:

            (command "_.MSPACE")
            (setvar "cvport" vpnum) ; set to matching vport number

            (setq vpPts (getViewportModelRect vpEnt)) ; get corners after going inside matching vport
            (setq p1 (car vpPts))
            (setq p2 (cadr vpPts))

            (command "_.Zoom" ".9x")
            (setq ssC (ssget "_C" p1 p2))

Now it'll work.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 12 of 13

LeoManu
Enthusiast
Enthusiast

Hi, thanks for the fixes they worked great!
I’m having an issue with some drawings where the viewports have “desynchronized” UCS/WCS coordinates.

That means, if I take the viewport points and apply getViewportModelRect, it returns coordinates that are different from what the viewport is actually showing.

I was able to confirm this with this:

 

(defun c:testVpTrans ( / vpEnt vpObj cen wid ht xmin xmax ymin ymax p1 p2 p3 p4)
  (vl-load-com)

  (setq vpEnt (car (entsel "\nSelect viewport: ")))

  (setq vpObj (vlax-ename->vla-object vpEnt))
  (setq cen (vlax-get vpObj 'Center))
  (setq wid (vlax-get vpObj 'Width))
  (setq ht  (vlax-get vpObj 'Height))
  (setq xmin (- (car cen) (/ wid 2.0)))
  (setq xmax (+ (car cen) (/ wid 2.0)))
  (setq ymin (- (cadr cen) (/ ht 2.0)))
  (setq ymax (+ (cadr cen) (/ ht 2.0)))

  (setq p1 (trans (list xmin ymin 0.0) 3 2))
  (setq p2 (trans (list xmax ymax 0.0) 3 2))
  (setq p3 (trans (list xmin ymax 0.0) 3 2))
  (setq p4 (trans (list xmax ymin 0.0) 3 2))

  (command "_.MSPACE")
  (command "_.PLINE" p1 p3 p2 p4 "C")

  (princ)
)

 

I’m not sure if it’s caused by a corrupted file or if it can be fixed with some viewport setting, Thanks!

0 Likes
Message 13 of 13

paullimapa
Mentor
Mentor
Accepted solution

Ok found the problem with the original getViewportModelRect function which is missing one more trans function step:

        (setq p1 (trans (list xmin ymin 0.0) 3 2))
        (setq p2 (trans (list xmax ymax 0.0) 3 2))
        ; add the following lines of code
        (setq p1 (trans p1 2 0))
        (setq p2 (trans p2 2 0))
        ;

I've updated CleanEmptyVP.lsp and reposted in Msg #11

But as for your testVpTrans.lsp function I made even more changes because you're missing a sequence of steps CleanEmptyVP.lsp follows:

; testVpTrans tests getViewportModelRect function to get proper vp coordinates from ps to ms
; OP:
; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/delete-empty-viewports/m-p/13887022#M167881
(defun c:testVpTrans 
  ( / vpEnt vpObj cen wid ht xmin xmax ymin ymax p1 p2 p3 p4 osnapcoord vpnum) ; localize variables
  (vl-load-com)
  
; chk if in Model 
  (if (not (zerop (getvar "TILEMODE"))) 
   (setvar "CTAB" (nth 0 (layoutlist))) ; then goto first layout 
  )
;  
; make sure is in pspace
  (command "_.PSPACE")
;
  
  (setq vpEnt (car (entsel "\nSelect viewport: ")))
  
; get vport number
  (setq vpnum (getpropertyvalue vpEnt "number"))
;  
; goto mspace to process 
  (command "_.MSPACE")
  
; set to the selected vport
  (setvar "CVPORT" vpnum)
;

  (setq vpObj (vlax-ename->vla-object vpEnt))
  (setq cen (vlax-get vpObj 'Center))
  (setq wid (vlax-get vpObj 'Width))
  (setq ht  (vlax-get vpObj 'Height))
  (setq xmin (- (car cen) (/ wid 2.0)))
  (setq xmax (+ (car cen) (/ wid 2.0)))
  (setq ymin (- (cadr cen) (/ ht 2.0)))
  (setq ymax (+ (cadr cen) (/ ht 2.0)))

  (setq p1 (trans (list xmin ymin 0.0) 3 2))
  (setq p2 (trans (list xmax ymax 0.0) 3 2))
  (setq p3 (trans (list xmin ymax 0.0) 3 2))
  (setq p4 (trans (list xmax ymin 0.0) 3 2))
  
; add the following lines of code  
  (setq p1 (trans p1 2 0))
  (setq p2 (trans p2 2 0))
  (setq p3 (trans p3 2 0))
  (setq p4 (trans p4 2 0))
; 
; save current osnapcoord setting
  (setq osnapcoord (getvar "OSNAPCOORD"))
  (setvar "OSNAPCOORD" 1) ; set keyboard entry to override osnaps 
;  
  
  (command "_.PLINE" p1 p3 p2 p4 "C")

; go back to pspace
  (command "_.PSPACE")
;
  
; Restore original setting
  (setvar "OSNAPCOORD" osnapcoord)  
;  
; goto Model to review
  (setvar "CTAB" "MODEL")
;  
  (princ)
)

BTW, in the viewports error.dwg there are actually two VPORTS that overlap with one looking at a different location in Model.

paullimapa_0-1762647386841.png

I moved one of the VPORTS to the right and after running testVpTrans on that one the PLINE is drawn below the other in Model looking at an empty area.

paullimapa_2-1762647453473.png


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes