Visual LISP, AutoLISP and General Customization

Reply
Active Contributor
weedseed85
Posts: 33
Registered: ‎02-05-2013
Message 1 of 9 (942 Views)
Accepted Solution

Field update customscale viewport

942 Views, 8 Replies
02-22-2013 04:50 AM

Dear autocad / lisp users,

 

Could you please help me with my question.

 

I'm trying to create a field in a block (titleblock) that will automaticly update when I 

change the viewportscale.

It's mostly only 1 viewport, sometimes a second of even 3rd but, they are not important to the titleblock.

 

I've read aboud fields and diesel expressions. I've tried and it works. there is only 1 problem,

It only works with the object (when field expresssion, object, custom scale) in this case the viewport

pressent at that time. 

When i use the same field with the same expressions, it does not recognize the viewport/object.

 

Is there a way to make the field, diesel expression or even something else, work without it's need for a

object name. Perhabs that the expression gets the viewportname from a lisp, something like:

 

(setq ss(ssget "X")) ;some thing like this

 Can it be done?

 

Anny help will be great.

 

Greets Michel

 

 

*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 2 of 9 (939 Views)

Re: Field update customscale viewport

02-22-2013 04:56 AM in reply to: weedseed85

weedseed85,

 

Hope that helps

Henrique

 

Vp_Field.PNG

Active Contributor
weedseed85
Posts: 33
Registered: ‎02-05-2013
Message 3 of 9 (878 Views)

Re: Field update customscale viewport

02-28-2013 12:47 AM in reply to: hmsilva

Dear Henrique,

 

Thank you for replying to my message.

Unfortunaly it's not what I'm looking for.

I've tried the customscale field, and it works. The only problem is. It works with the 

current viewport, pressent at the time i place the field.

 

In other words. 

The field is given a certain name, for example: viewport12048v, This name is given to

the field expression. When I copy or place the field in a other drawing or layout tab. 

It does not reconize the name of the viewport.

 

Do you perhabs know a way to work around this... Name Problem?

 

Anny suggestions will be fine.

 

Greets Michel

*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 4 of 9 (872 Views)

Re: Field update customscale viewport

02-28-2013 03:09 AM in reply to: weedseed85

Michel,
after replying, I realized that I was giving the same solution that you already had.
Unfortunately, I don't have way to help you with the field problem,  but if meanwhile I find something that can help, I come back to to share.

 

Cheers

Henrique

Mentor
coopdetat
Posts: 195
Registered: ‎03-25-2011
Message 5 of 9 (862 Views)

Re: Field update customscale viewport

02-28-2013 07:01 AM in reply to: weedseed85

For a field to provide the viewport scale it must have a reference from which to get/update the scale.  It is my understanding that the only way to access the viewport scale field is through the SheetSet reference or the object itself and the viewport must be present.  

 

It is not possible to have a field include the scale for a non-existent viewport as it has no way of knowing what that scale is.  Prior to using Sheet Sets I would get a viewport scale by calculating it from the variables associated with the view.  You could do this and update your titleblock with it but if you have more than one viewport you may have more than one scale. 

 

You say that you may have multiple viewports or just one viewport and the existence of the viewport is not important to your title block scale field.  It seems that just having fixed text for the scale would best suit your needs. 

 

If you want it to reflect your viewport scale automatically then you have multiple problems to solve.

 

1) you need a reactor to fire when you open the drawing or make it current.

2) you need to find the correct viewport and calculate or otherwise obtain its scale.

3) you need to update the title block with the scale.

 

If you can solve the reactor and viewport selection problems I know how to calculate and update the scale.

 

P.S. it may work to obtain the object ID and format the string to include the object ID. It should match what your system shows for the object custom scale per hmsilva's post (see the bottom of hmsilva's posted image).

 

Or, put a sheetset callout block in the viewport (does not need to be visible) and then get the field value from it and put it in your titleblock.  The callout block will automatically update.  Maybe the titleblock will as well if it has the same value?

---------------------------------------------Signature--------------------------------------------
Civil Design Professional Since 1983 (Intergraph), AutoCAD since 1989

It is said that a fool's voice is known by multitude of words... I'm
just writing this stuff instead of saying it outloud... that's my loophole.

Windows 7 Professional 64-bit - Service Pack 1
Intel﴾R﴿ Core﴾TM﴿ i7-3820 CPU 3.60GHz; 16 GB DDR3 Dual Channel RAM
nVidia Quadro 4000; AutoCAD Civil 3D 2013, sp1
Active Contributor
weedseed85
Posts: 33
Registered: ‎02-05-2013
Message 6 of 9 (837 Views)

Re: Field update customscale viewport

03-01-2013 03:26 AM in reply to: coopdetat

Dear Coopdetat,

 

Thank you verry mucht for you help.

 

I don't know if I'll be able to create something with your input. But I'll sure try.

 

I was thinking, working, on a way to get the Viewport Custom Scale from the Viewport,

without clicking or selection the viewport. Since I have only 1 (99% of the time) viewport

it shouldn't be so hard.

 

I've found something I think, can be formed into something I want.

It's called VPSCALE.lsp, from the Express tools.

 

It works perfect. The only problem is, I have to tell the lisp where to find the correct viewport.

Here is the code:

 

;;;
;;;    VPSCALE.LSP
;;;    Copyright © 1999 by Autodesk, Inc.
;;;
;;;    Your use of this software is governed by the terms and conditions of the
;;;    License Agreement you accepted prior to installation of this software.
;;;    Please note that pursuant to the License Agreement for this software,
;;;    "[c]opying of this computer program or its documentation except as
;;;    permitted by this License is copyright infringement under the laws of
;;;    your country.  If you copy this computer program without permission of
;;;    Autodesk, you are violating the law."
;;;
;;;    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
;;;    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
;;;    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
;;;    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
;;;    UNINTERRUPTED OR ERROR FREE.
;;;
;;;    Use, duplication, or disclosure by the U.S. Government is subject to
;;;    restrictions set forth in FAR 52.227-19 (Commercial Computer
;;;    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
;;;    (Rights in Technical Data and Computer Software), as applicable.
;;;
;;;  ----------------------------------------------------------------
 
;    find the scale of a viewport relative to paper space
;    Carl Bethea  11 April 91
;
;     Paul Vine   20 April 1999   Ported to 2000.
;
;--- paper -------------------------------------------------
; returns T if in paper space
(defun paper ()
   (> 2 (getvar "cvport")(getvar "tilemode")) ; port=1 & tile=0
)
;
;--- getx --------------------------------------------------
; return <nth> dotted pair of the extended entity data
; from an entity association list <data>
;
(defun getx (n data)
(nth n (cdadr (assoc -3 data)))
)
;
;
;
;--- c:vpscale ----------------------------------------------
; get the xp scale factor of a pspace viewport
;
(defun c:vpscale (/ ent data cvsize cvhgt units vpna flag)
 (cond
  ((not (equal 0 (getvar "tilemode")))
   (princ "\n  Command not allowed unless TILEMODE is set to 0  ") 
  )
  ((and (/= 1 (getvar "cvport"))
        (setq vpna (acet-currentviewport-ename))
        (equal 1 (logand 1 (cdr (assoc 90 (entget vpna)))))
   )
   (princ "\n  Command not allowed in perspective view  ") 
  )
  (T
 
      (acet-error-init
        (list
          (list "cmdecho" 0
                "luprec" (getvar "luprec")
                "dimzin" 8
          )
          T     ;flag. True means use undo for error clean up.
 
        );list
      );acet-error-init
 
 
      (if (paper)
        ;(setq ent (car (entsel "\nSelect edge of viewport: ")))
 
       ;;Added the following code to replace the above line.  Irregularly shaped floating viewports actuall
       ;;consist fo two entities (a pline and a viewport) with reactors on each other to point to each other
       ;;so a simple (entsel) returned a pline instead of a viewport. Had to uise the built-in filtering
       ;;capability of 'acet-ui-single-select' to get around this problem.
       (progn
          (while (not flag)
           (princ "\nSelect edge of viewport.")
           (setq ent (acet-ui-single-select '((0 . "viewport")) T )) ;setq
           (if (and ent
                    (= 1 (logand 1 (cdr (assoc 90 (entget ent)))))
               )
               (progn
                 (princ "\nViewports with perspective view on are not allowed.")
                 (setq flag nil)
               );progn
               (setq flag T)
           );if
          );while
        );progn
        (setq ent (acet-currentviewport-ename))
      )
      (cond
        ((and
            ent
            (setq data (entget ent '("ACAD")))
            (= "VIEWPORT" (acet-dxf 0 DATA))
         );and
          (setq cvhgt  (acet-dxf 41 DATA)  ; viewport height
                cvsize (cdr (getx 6 data))    ; viewsize from extended data
          )
          (prompt "\nPS:MS == ")
          (cond
            ((< cvsize cvhgt)
              (princ (rtos (/ cvhgt cvsize) 2))
              (princ ":1")
            )
            (T (princ "1:")
              (princ (rtos (/ cvsize cvhgt) 2))
            )
          );cond
          (setq units (getvar "lunits"))
          (setvar "luprec" 8)
          (cond
            ((= units 4)
              (prompt (strcat "\nViewport Scale: " (rtos (/ 12 (/ cvsize cvhgt))) " = 1'-0\""))
            )
            ((= units 3)
              (prompt (strcat "\nViewport Scale: 1\" = " (rtos (/ cvsize cvhgt))))
            )
          )
        )
        (T (prompt " no viewport found."))
      );cond
      (acet-error-restore)                                  ; Retsore values
  )
 );cond close 
  (princ)
);c:vpscale


(princ)

 

I've tried serveral things, listed below:

 

(setq ss (ssget "_X" (list (cons 410 (getvar "ctab")) '(0 . "VIEWPORT")))vp (ssname ss 0))
; Unfortunaly, I don't have the knowlage to put this into the, well written lisp.

(command "mspace") ; worked once... after the one time it keeps giving error's about not knowing the mpsace command.

(setq RecivedVpScale (rtos (/ cvsize cvhgt)))
; The output of the lisp it written to this $Variable.
; The last thing to do with it is, (rtos ...number/$var... 2 1) to get a clean output.


 

If i'm able to retrieve the last numers of the VpCustom Scale (cannoscale) I could use a little lisp

routine to place it into my titleblock, like this:

1: (static value) + the ouput of the lisp.

 

I believe that, or something like that, could work :smileyvery-happy:

 

 

I hope i wrote my question / remarks a little understandable.

 

Anny suggestions for the above "story / stuff" are welcome.

 

 

 

Greets Michel

*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 7 of 9 (824 Views)

Re: Field update customscale viewport

03-01-2013 03:46 PM in reply to: weedseed85

Michel,
as far as I understood, you have a title block  with several attributes, and a field in one of the attributes linked to
the viewport scale, and if you copy to another drawing or other viewport, the field is no longer linked to the new viewport.
This code reconnect the field to the new viewport, selecting the new viewport and the text field in the attribute block.
This code was written, from one that was posted here in Discussion Groups, a few years ago, by OwenWhitehouse, where he managed to discover the objectid if the platform was x64.

 

(defun c:test (/ vpObj fldObj vpID util fldtxt)
  (vl-load-com)
  (setq	vpObj  (vlax-ename->vla-object
		 (car (nentsel "\nSelect the viewport: "))
	       )
	fldObj (vlax-ename->vla-object (car (nentsel "\nSelect the Field: ")))
	vpID   (vla-get-objectid vpObj)
  );; setq
  (if (> (vl-string-search "x64" (getvar "platform")) 0)
    (progn
      (setq util (vla-get-Utility
		   (vla-get-activedocument (vlax-get-acad-object))
		 )
	    vpID (vlax-invoke-method
		   util
		   "GetObjectIdString"
		   vpObj
		   :vlax-False
		 )
      );; setq
    );; progn
    (setq vpID (vl-princ-to-string (vla-get-Objectid vpObj)))
  );; if
  (setq	fldtxt	(strcat	"%<\\AcObjProp.16.2 Object(%<\\_ObjId "
			vpID
			">%).CustomScale \\f \"%sn\">%"
		)
  )
  (vla-put-textstring fldObj fldtxt)
  (vla-update fldObj)
  (vla-regen (vla-get-activedocument (vlax-get-acad-object))
	     1
  )
  (princ)
);; test

 

hope that helps

Henrique

Active Contributor
weedseed85
Posts: 33
Registered: ‎02-05-2013
Message 8 of 9 (800 Views)

Re: Field update customscale viewport

03-04-2013 02:49 AM in reply to: hmsilva

Dear Henrique,

 

Thank you verry, verry much for your post. 

 

I think i wlll be able to create something so suite my needs with this lisp.

It looks perfect.

 

In the meanwhile I've even found a way (lisp) to extract the custom viewportscale.

In combination with the lisp you gave me. I could create a lisp that will update the

block with the extracted vpscale.

 

It's going to be perfect :smileyvery-happy:

 

Again, Thank you verry verry much.

 

Greets, 

Michel

 

 

 

here is the code to extract the custom vpscale:

 

 

 

For those who might have intrest in getting the custom viewportscale:

The lisp extracts the viewportscale in mm (milimeters)

If you want the scale to return as INCH, you just have to turn the output to

INCH. 1mm = 25.4mm

 

(defun C:vpsc ()	;/ a ts n vpsf th index b1 b c d b2)  		; defines function and variables
  (setq ss (ssget "X" (list '(0 . "Viewport")(cons 69 2))))		; defines selection set '(cons 69 1)(cons 410 "*") 
  (setq n (sslength ss))                                   	 	; gets number of items selected
  (setq index 0)                                           	 	; sets counter for loop to 0
  (repeat n                                               	 	; begin loop for number of items
    (setq ent (ssname ss index))                 				; get the entity name
    (setq entnm (entget (ssname ss index)))             	    ; get the entity name
	;(princ entnm)												; show ent data
	(setq index (+ index 1))                          		   	; adds to counter
	(setq entyp (assoc 0 entnm))                      	     	; pulls out entity type 
    (if (= "VIEWPORT" (cdr entyp))                          	; checks for text entity
		(progn                                          		; begins actual program 
			(setq vpnme (cdr (assoc 410 entnm)))              	; gets viewport name
			(princ "\nViewportname = ")(princ vpnme)
			(setq data (entget ent '("ACAD*")))
 
			(setq cvhgt  (acet-dxf 41 DATA))  					; viewport height
			(setq cvsize (cdr (getx 6 data)))    				; viewsize from extended data
			(princ (strcat "\n1:" (rtos (/ cvsize cvhgt) 2 0)))	;Print output, 1: scale
			(setq gvpsc (rtos (/ cvsize cvhgt) 2 0))			;Place output into $var "gvpsc"
		)														; end progn
    )															; ends if
  )																; ends loop
  (print)                                                   	; cleans command line
)

(defun getx (n data)
(nth n (cdadr (assoc -3 data)))
)

;(princ "VPSC Loaded...scales text to viewport scale.")     		; loading information

 

*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 9 of 9 (797 Views)

Re: Field update customscale viewport

03-04-2013 02:53 AM in reply to: weedseed85

You're welcome, Michel
Glad I could help

 

Henrique

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community