Author Topic: Eliminate the Paper Space Viewport from a list of all viewports on a layout  (Read 17393 times)

0 Members and 1 Guest are viewing this topic.

Sdoman

  • Guest

I am trying to construct a list containing a sublist for each paperspace layout in the drawing.  The Car of a sublist will be the layout name (string). The Cdr of a sublist will be another list containing all paperspace vport objects references for that particular layout.

Here is an example of a list I am trying to construct:

 
Code: [Select]
(("Layout1"
     (#<VLA-OBJECT IAcadPViewport 064a9324>
      #<VLA-OBJECT IAcadPViewport 064a8c54>
     )
   )
    ("Layout2"
      (#<VLA-OBJECT IAcadPViewport 064a88a4>
       #<VLA-OBJECT IAcadPViewport 064a84f4>
       #<VLA-OBJECT IAcadPViewport 064adc54>
      )
    )
    ...
  )

My problem is I don't want to include the paperspace viewport.  I thought I could eliminate the paperspace viewport by using ssget with a dxf filter.  However I am getting mixed results, sometimes it works, othertimes it doesn't.  So I am not sure if this is a correct way to accomplish this task.

Here's the code I have so far.  The first function is what I am working on.  The other two are supporting functions:

Code: [Select]
(defun sd:VpList (/ ss rslt)
  ;;
  ;; Returns a list of layout names and vports objects
  ;; Requires subfunction LayoutList< and ss->objlst
  ;;
  (foreach layout (sd:LayoutList<)
    (if (setq ss (ssget "x"
                        (list '(0 . "VIEWPORT")
                              (cons 410 layout)
                              '(-4 . ">") 
                              '(68 . 0)  ;_ viewport status
                        )
                 )
        )
      (setq rslt (cons (list layout (sd:ss->objlst ss)) rslt))
    )
  )
  (reverse rslt)
)

Code: [Select]
(defun sd:LayoutList< (/ layout name index)
  ;; sdoman
  ;; Returns list of layout names sorted by taborder
  ;; Excludes the "Model" layoutname
  ;;
  (vlax-for layout (vla-get-layouts
                  (vla-get-activedocument (vlax-get-acad-object))
                )
    (setq name  (cons (vla-get-name layout) name)
          index (cons (vla-get-taborder layout) index)
    )
  )
  (cdr (mapcar '(lambda (x) (nth x name)) (vl-sort-i index '<)))
)

Code: [Select]
(defun sd:ss->objlst (ss / n lst)
  ;; Returns a list of vla-objects given a selection set
  (cond ((= (type ss) 'PICKSET)
         (setq n 0)
         (repeat (sslength ss)
           (setq lst (cons (vlax-ename->vla-object (ssname ss n)) lst)
                 n   (1+ n)
           )
         )
         (reverse lst)
        )
  )
)

Thanks,
Steve

T.Willey

  • Needs a day job
  • Posts: 5251
How about if you check for dxf code 69.  I think that if it's 1 then it is the paper space viewport.
Code: [Select]
(defun sd:VpList (/ ss rslt)
  ;;
  ;; Returns a list of layout names and vports objects
  ;; Requires subfunction LayoutList< and ss->objlst
  ;;
  (foreach layout (sd:LayoutList<)
    (if (setq ss (ssget "x"
                        (list '(0 . "VIEWPORT")
                              (cons 410 layout)
                              '(-4 . ">") 
                              '(69 . 0)  ;_ viewport number
                        )
                 )
        )
      (setq rslt (cons (list layout (sd:ss->objlst ss)) rslt))
    )
  )
  (reverse rslt)
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Sdoman

  • Guest
How about if you check for dxf code 69.  I think that if it's 1 then it is the paper space viewport.
Code: [Select]
(defun sd:VpList (/ ss rslt)
  ;;
  ;; Returns a list of layout names and vports objects
  ;; Requires subfunction LayoutList< and ss->objlst
  ;;
  (foreach layout (sd:LayoutList<)
    (if (setq ss (ssget "x"
                        (list '(0 . "VIEWPORT")
                              (cons 410 layout)
                              '(-4 . ">") 
                              '(69 . 0)  ;_ viewport number
                        )
                 )
        )
      (setq rslt (cons (list layout (sd:ss->objlst ss)) rslt))
    )
  )
  (reverse rslt)
)

Tim

Thanks but that doesn't to work for me.  Wait let me check something...

Ok if I change the filter to: '(-4 . ">") '(69 . 1), it *seems* to work.  Going to do some testing...


fixd typo: dxf 69 -> 1

« Last Edit: July 11, 2006, 05:28:49 PM by 'steved »

T.Willey

  • Needs a day job
  • Posts: 5251
You are right Steve.  I meant to put '(69 . 1).  It worked on a quick little test I did here.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Edit: Modified to test for valid selection set, lest it bomb.

Not sure I follow but this quick & dirty --

Code: [Select]
(defun foo ( / ss result key exist )
    (if
        (setq ss
            (ssget "x"
               '(   
                    (0 . "VIEWPORT")
                    (-4 . "!=") 
                    (69 . 1)
                    (-4 . ">")
                    (68 . 0)
                )
            )
        )
        (vl-sort
            (foreach ename (mapcar 'cadr (ssnamex ss))
                (setq result
                    (if
                        (setq exist
                            (assoc
                                (setq key (cdr (assoc 410 (entget ename))))
                                result
                            )
                        )
                        (subst
                            (list key
                                (cons
                                    (vlax-ename->vla-object ename)
                                    (cadr exist)
                                )
                            )
                            exist
                            result
                        )
                        (cons
                            (list key (list (vlax-ename->vla-object ename)))
                            result
                        )
                    )
                )   
            )
           '(lambda (a b) (< (car a) (car b)))
        )
    )   
)

Spews this --

Code: [Select]
(   
    (   "Layout1"
        (   #<VLA-OBJECT IAcadPViewport 02c1e9f4>
            #<VLA-OBJECT IAcadPViewport 02c36734>
        )
    )
    (   "Layout2"
        (
            #<VLA-OBJECT IAcadPViewport 02c1e8c4>
            #<VLA-OBJECT IAcadPViewport 02c2b904>
            #<VLA-OBJECT IAcadPViewport 02c365b4>
        )
    )
)

Use [abuse|discard|ignore] as you see fit.
« Last Edit: July 11, 2006, 06:20:32 PM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Nice code Michael.  I see more and more post with people using "ssnamex".  Guess it's time to learn a new trick.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Thanks Tim, please see the edit.

PS: A nod to our friend Evgeniy who illuminated the use of ssnamex.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Sdoman

  • Guest
Nice one MP.  Your code works well! And the ssget filter you used is interesting.

And what Tim said.  The ssnamex function is something I rarely have used.  That's so cool how you used it to get a list of enames.




MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Thanks Steve, just havin' some good ol' lispin' fun. Glad if it helps even if just a little.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Sdoman

  • Guest
MP,

It does help and thank you very much for posting.  I must admit to being a bit overwhelmed at first while trying to understand your algorithm.  But now that I've had a chance to study it, I find the code within the foreach loop really interesting.

Could you please comment on your ssget filter?  The help files totally confused me on which dxf code to use.  I think what your are filtering is: select all viewports which are on and not "Thee Paper Space" viewport. Right?



MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Hi Steve. As I understand it ssget filtering, without -4 groups to specify otherwise, employs implied and all the way.

So the filter as written says --

Select all entities that are viewports AND have an ID that is not equal to 1 (paperspace) AND have a status that is greater than 0 (on and active).

That is what I thought you wanted; hope I didn't veer too far of the desired track.

:)

Happiness thru drugs; oh bliss.

PS: My pleasure Steve.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Sdoman

  • Guest
MP,

Coolness.  That is exactly what I want. Thanks.

Have a nice bliss : )

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Thanks Steve, that makes me happer than a dung beetle at an elephant parade, or something like that.

 :lol:
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Sdoman

  • Guest
Shoot!  Still having problems:

I came to work this morning, fired up AutoCAD, opened my test drawing that contains several paperspace layouts, Then I loaded and the 'foo function.  It returned a list containing the data for the current layout, but not the others.  I suspect the ssget filter is the problem.  Perhaps when a drawing is first opened, the viewports are not activated until the layout the viewport is located on is made active.

Any ideas?  Attached is drawing file I am using for testing (saved as a2k file format).

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
I can't D/L from here (mumble ...). Try this --

Code: [Select]
(ssget "x"
   '(   
        (0 . "VIEWPORT")
        (-4 . "!=") 
        (69 . 1)
        (-4 . "!=")
        (68 . 0)
    )
)

It limits the selection to viewports that are not off, which means viewports that are on but not active (or visible, like off screen, maxactvp exceeded yada) can be selected. HTH.

/Shrug.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst