Code to rotate Multiple UCS of viewports with Manual and automatic options.

Code to rotate Multiple UCS of viewports with Manual and automatic options.

arpansark0544TCX
Advocate Advocate
458 Views
7 Replies
Message 1 of 8

Code to rotate Multiple UCS of viewports with Manual and automatic options.

arpansark0544TCX
Advocate
Advocate

Dear All,

 

I am working on a code which can rotate UCS of viewports.

There are 2 methods.

1. Manual : The user will select the viewports he want to rotate.

2.Automatic: UCS of all the viewports will get rotate.

 

I am facing issues . Kindly help.

 

Code below for Manual and Automatic(not working, Contains error!) :

(defun c:RotateUCSInLayouts (/ doc layouts layout angle mode selectedVPorts vpList vp ent layoutName ownerID currentLayout)
  (vl-load-com)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))

  ;; Get the rotation angle from the user
  (setq angle (getreal "\nEnter UCS rotation angle in degrees: "))

  (if angle
    (progn
      ;; Ask the user for mode of operation
      (initget "M A")   
      (setq mode (getkword "\nApply to [Manual (M) / Automatic (A)] <M>: "))
      (if (null mode) (setq mode "M")) ;; Default to Manual if not specified

      ;; Store the current active layout
      (setq currentLayout (vla-get-Name (vla-get-ActiveLayout doc)))

      ;; If manual mode, let the user select viewports (only in the current layout)
      (if (= mode "M")
        (progn
          (princ "\nSelect Viewports in the current Layout:")
          (setq selectedVPorts (ssget '((0 . "VIEWPORT")))) ;; User selects viewports
          (if selectedVPorts
            (progn
              (setq vpList '())
              (foreach vp (mapcar 'cadr (ssnamex selectedVPorts))
                (setq ent (vlax-ename->vla-object vp))
                (if (and ent (vlax-property-available-p ent 'OwnerID))  ;; Ensure it's a valid VLA object
                  (progn
                    ;; Get the owner (paper space block) of the viewport
                    (setq ownerID (vla-get-OwnerID ent))
                    ;; Get the layout associated with the viewport
                    (setq layout (vla-Item (vla-get-Layouts doc) ownerID))
                    (setq layoutName (vla-get-Name layout))
                    
                    ;; Ensure the selected viewport belongs to the current layout
                    (if (= (strcase layoutName) (strcase currentLayout))
                      (setq vpList (cons ent vpList))
                      (progn
                        (princ "\nViewports from multiple layouts cannot be selected in Manual mode. Exiting.")
                        (exit)
                      )
                    )
                  )
                  (princ "\nSelected object is not a valid viewport. Skipping.")
                )
              )
            )
            (progn
              (princ "\nNo viewports selected. Exiting.")
              (exit)
            )
          )
        )
      )

      ;; Process each layout
      (setq layouts (vla-get-layouts doc))
      (vlax-for layout layouts
        (if (/= (strcase (vla-get-name layout)) "MODEL")  ; Skip Model Space
          (progn
            (setvar "TILEMODE" 0)  ;; Ensure we are in Layout Mode
            (if (vlax-property-available-p layout 'Name))  ;; Ensure it's a valid layout
              (progn
                (vla-put-ActiveLayout doc layout) ;; Activate the layout
                (princ (strcat "\nProcessing layout: " (vla-get-Name layout)))

                ;; If Automatic mode OR current layout is selected, apply changes
                (if (or (= mode "A") (= (strcase (vla-get-Name layout)) (strcase currentLayout)))
                  (progn
                    ;; If in Manual Mode, process each selected viewport
                    (if (= mode "M")
                      (foreach vp vpList
                        (if (vlax-property-available-p vp 'Number))  ;; Ensure it's a valid paper space viewport
                          (progn
                            (princ (strcat "\nProcessing viewport: " (vl-princ-to-string vp)))
                            (if (vl-catch-all-error-p
                                  (vl-catch-all-apply
                                    '(lambda ()
                                      (vla-put-ActivePViewport doc vp) ;; Activate viewport
                                      (command "_.MSPACE") ;; Enter Model Space
                                      (command "_.UCS" "Z" angle) ;; Rotate UCS by given angle
                                      (command "_.PLAN" "Current") ;; Align view to UCS
                                      (command "_.PSPACE") ;; Return to Paper Space
                                    )
                                  )
                                )
                              (princ "\nError processing viewport. Skipping.")
                            )
                          )
                          (princ "\nInvalid viewport. Skipping.")
                        )
                      )
                      ;; If Automatic Mode, apply UCS change to all viewports in each layout
                      (progn
                        (command "_.MSPACE") ;; Enter Model Space
                        (command "_.UCS" "Z" angle) ;; Rotate UCS by given angle
                        (command "_.PLAN" "Current") ;; Align view to UCS
                        (command "_.PSPACE") ;; Return to Paper Space
                      )
                    )
                  )
                )
              )
              (princ "\nInvalid layout. Skipping.")
            )
          )
        )
      )
      (princ "\nUCS rotated and PLAN set in selected layouts.")
    )
    (princ "\nInvalid angle entered. Operation aborted.")
  )
  (princ)
)

 

 

Below is the working code for the Automatic: 

(defun c:AutoRotateUCS_Layouts (/ doc layouts layout angle vports vp)
  (vl-load-com)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))

  ;; Get the rotation angle from the user
  (setq angle (getreal "\nEnter UCS rotation angle in degrees: "))

  (if angle
    (progn
      (setq layouts (vla-get-layouts doc))
      (vlax-for layout layouts
        (if (/= (strcase (vla-get-name layout)) "MODEL")  ; Skip Model Space
          (progn
            (setvar "TILEMODE" 0)  ;; Ensure we are in Layout Mode
            (vla-put-ActiveLayout doc layout) ;; Activate the layout

            ;; Get all viewports in the layout
            (setq vports (vla-get-ActiveLayout doc))
            (if vports
              (progn
                (command "_.MSPACE") ;; Enter Model Space
                (command "_.UCS" "Z" angle) ;; Rotate UCS by given angle
                (command "_.PLAN" "Current") ;; Align view to UCS
                (command "_.PSPACE") ;; Return to Paper Space
              )
              (princ "\nNo viewport found in layout: " (vla-get-name layout))
            )
          )
        )
      )
      (princ "\nUCS rotated and PLAN set in all layouts.")
    )
    (princ "\nInvalid angle entered. Operation aborted.")
  )
  (princ)
)

 

0 Likes
459 Views
7 Replies
  • ucs
Replies (7)
Message 2 of 8

ВeekeeCZ
Consultant
Consultant

You don't set UCS by selecting an object?

0 Likes
Message 3 of 8

paullimapa
Mentor
Mentor

For the automatic check out this thread which shows examples on selecting all vports in current layout except the pspace itself

https://forums.augi.com/showthread.php?164589-SSGET-Viewports-Returns-More-Viewports-Than-There-Are


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

paullimapa
Mentor
Mentor

Here’s another interesting example for the automatic in using (vports) function to select all vports in current layout

https://adndevblog.typepad.com/autocad/2013/02/zoom-all-in-all-viewports.html


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

Sea-Haven
Mentor
Mentor

Something like this. The image shows rectangs representing the layout viewport at a selected scale, it auto walks along a line or pline. Next step is make the layouts automatically. The reason for 2 steps is to make sure rectangs are ok before making layouts.

layout 1.png

Annother version is for manual insert rectangs as horizontal direction, both can be used in make layouts.

Happy to discuss further

 

 

 

0 Likes
Message 6 of 8

arpansark0544TCX
Advocate
Advocate

My code is working fine for the automatic.

I am having issue when i am selecting viewports manually. The code should go into each viewport and then rotate the UCS considering z as reference and rotating y and x axis as per the user preference. But the error is that it is not identifying the selected viewports.  

 

"Enter UCS rotation angle in degrees: 180
Select Viewports in the current Layout:
Select objects: Specify opposite corner: 2 found
Select objects: ; error: bad argument type: lentityp (0 (-9.82628 34.6227 0.0))"

 

0 Likes
Message 7 of 8

paullimapa
Mentor
Mentor

This is the lines of code that I would use for the manual vport selection:

      (if (= mode "M")
        (progn
          (princ "\nSelect Viewports in the current Layout:")
          (setq selectedVPorts (ssget '((0 . "VIEWPORT")))) ;; User selects viewports
          (if selectedVPorts
            (progn
              (command "_.Mspace") ;; Enter Model Space
              (foreach vp (mapcar 'cadr (ssnamex selectedVPorts))
               (setq vpnum (cdr (assoc 69 (entget vp)))) ; get vport number
               (setvar "cvport" vpnum) ; set vport number as current
               (command "_.UCS" "Z" angle) ;; Rotate UCS by given angle
               (command "_.PLAN" "Current") ;; Align view to UCS             
              ) ; foreach
              (command "_.PSPACE") ;; Return to Paper Space             
            )
          )
        )
      )

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

Sea-Haven
Mentor
Mentor

In the code I hinted at above its a 2 step process make rectangs then make the layouts, can be ran multi times adding more layouts. Even if you use version 2 of the make rectangs which is make rectangs horizontally and just pick a centre point, you can move, delete or rotate the rectang, then just select all rectangs and layouts are made. Tested on dwg's from here made 66 in one go. Happy to talk more you need to setup the rectangs matching the title block to be used.

SeaHaven_0-1740644578926.png

 

0 Likes