Macro to Note Dimensions in CAD

Ace coders fine-tune a macro for noting dimensions in architectural style. March 17, 2005

Question
I just found a macro that dimensions arcs, but there is a problem when used. The dimension that appears does not take on the characteristics of my dimension style. It takes on the text size, but it only dimensions in decimals and I use architectural units. How can I rewrite this macro so that it will take on all of the characteristics of my dimension style? Is there a way I can write in a working name (dimarc) for this command so that I won't have to use the toolbar button every time?

Here is the macro:

^C^C_pedit;\;;_list;@;;_explode;last;_dimangular; @;t;$M=$(substr,$(getvar,PERIMETER),1,$(-,$(strlen,$(getvar,PERIMETER)),$(-,8,$(getvar,dimdec))));\

Forum Responses
(CAD Forum)
From contributor D:
Try this lisp routine.

;Save to dimarc.lsp file and
;type dimarc at the promt
;(rtos number [mode [precision]])
;1 Scientific
;2 Decimal


;3 Engineering (feet and decimal inches)
;4 Architectural (feet and fractional inches)
;5 Fractional
(defun c:dimarc ( / arclength center dimobj en endpoint obj startpoint)
(vl-load-com)
(while (not (setq en (car (entsel "\nSelect an Arc: "))))
(princ "\nMissed please try again: "))
(if (= (cdr (assoc 0 (entget en))) "ARC")
(progn
(setq Obj (vlax-ename->vla-Object en)
ArcLength (vla-get-ArcLength Obj)
Center (vlax-safearray->list (vlax-variant-value (vla-get-center obj)))
StartPoint (vlax-safearray->list (vlax-variant-value (vla-get-StartPoint obj)))
EndPoint (vlax-safearray->list (vlax-variant-value (vla-get-EndPoint obj))))
(setvar "CMDECHO" 0)
(command "_dimangular" en Center StartPoint EndPoint "\\")
(setq dimobj (entget (entlast))
dimobj (subst

(cons 1 (rtos ArcLength 4 5));<-------
(assoc 1 dimobj)dimobj))
(entmod dimobj))
(princ "\nThat ain't no arc"))
(princ))



From the original questioner:
Thanks. That actually worked, considering I've never done it before. Here's my recap: I went to vlisp (never been there before), typed in the ...string... and then used the command, but it was never saved. So I assume that's why it won't work in any other drawing. Any advice?


From contributor J:
Type vlisp
Enter the lisp routine
Save the lisp routine in a folder that you can find
In AutoCAD type appload
Click on the suitcase where it says start up suite
Navigate to the folder where you saved the lisp file and add it to your start up suite

Close AutoCAD, start AutoCAD and it will be there every time you open a new or old drawing

If you run the lisp routine from vlisp it will go away when you close the drawing and you will have to reload it every time you want to use it. By adding it to your start up suite, it will automatically load for you.



From the original questioner:
That's just what I needed - thanks.


From contributor B:
I too am a rookie when it comes to lisp routines. Is there a way to change modes on the fly? Some drawings may require (2) decimal format while others may require (4) architectural (ft and fractional) or others may need (5) fractional, etc. Thanks in advance for any further advice on this.


From the original questioner:
Correct me if I'm wrong, but the lisp file above lists all units in order to mimic the dim style, and not actually use it. For some reason, when I use it its dim-ing in arch units, but I actually use fractions with a suffix (") in order to dim in inches. So how do I ensure it uses the correct units and is there a way to rewrite the fraction units to incorporate the suffix?


From the original questioner:
Nix the units part - I found where you specified which to use (still trying to learn the lingo). But I've still yet to figure out where to add a suffix.


From contributor J:
See the section of the code above:
(cons 1 (rtos ArcLength 4 5));<-------
(assoc 1 dimobj)dimobj))
(entmod dimobj))
(princ "\nThat ain't no arc"))
(princ))

Replace it with this:
(cons 1 (strcat(rtos ArcLength 5 4)"\""));<-------
(assoc 1 dimobj)dimobj))
(entmod dimobj))
(princ "\nThat ain't no arc"))
(princ))

I changed the type to fractions by changing the #4 to a 5 in the statement (rtos ArcLength 4 5). The first # represents the type to display, hence the 1-5 list at the beginning of the post. The second # is the precision. When dealing with fractions (first # is set to 5), the precision is how the fraction is displayed.

1 = Whole number (if a dimension is 2 ½ it will read 2)
2 = nearest 1/4
3 = nearest 1/8
4 = nearest 1/16
5 = nearest 1/32 and so on

If you notice, the replacement code has something added (strcat(rtos ArcLength 5 4) “\“”)). Here is how this code fragment breaks down. The ArchLength is a variable that holds the actual arch length of the arc you selected. (Example: 15.7500)

Rtos is a lisp command that converts a real number (that’s a number that has a decimal in it) to a string (that is anything enclosed in quote marks “15.7500”). The two numbers you see after ArchLength tells Rtos how to convert the variable ArcLength. In this case, we told it to use fractions by putting the 5 in there and we want a precision of 1/16 so Rtos now returns “15 ¾”.

Now we add another lisp command strcat. This command combines several strings into one single string. Notice the “\””. This is a string that contains \”. Remember, a string always starts with a quote” and ends with a quote” so to turn \” into a string you add the starting and ending quotes “\”” (are you lost yet?). The \” will create the inch mark you asked for.

So strcat puts the two strings “15 ¾” and “\”” together to make 15 ¾”. Any questions?



From the original questioner:
Thanks so much - you have helped me tremendously. Now the command works!


From contributor J:
Contributor B, you can tackle your request two different ways.

First way:
1. Copy the lisp routine. Make your change to the setting you want. Rename the command name c:dimarc to c:dimarc2 or whatever is good for you, as long as it is not an existing AutoCAD command, and always leave the c:. The c: is what makes it available to type into the command window.

2. Do a save as new name.lsp

3. Repeat the procedure until you have a routine set up for each type that you want.

4. Now add them to your start up suite. You can either type the name of the routine or you can create a couple of buttons to call the various routines for you.

Example: if you named one of the routines c:dimarc2, make a button and enter the macro ^C^Cdimarc2; and it will call the routine when clicked. The ^C^C clears the last command. You don’t need to put the C: just the name and make sure you put the semicolon at the end.

Second way (on the fly):
Set up a couple of variables to take place of the type and precision and one for the prompt question response.

You can’t use the word type because it is a lisp command, so let's use typ and prec.

Now set up the prompt question you will be asked.

To keep from entering bad input, we will use the initget command to limit what the response will be. (initget “S D E A F” 1) the s is for Scientific. The d is for decimal and so on. You can delete the letter of the ones that you don’t want, just make sure there is a space between each letter.

Now prompt for the answer (answ is the variable that will hold the prompt answer).
(setq answ (strcase(getkword “\nScientific,Decimal,Enginerring,Architecural,Fractional:”)))
Just type the first letter for what you want. The strcase will convert anything you type to an uppercase letter.

Now write a couple of if statements to set the two variables to what you want.

I suggest that you predetermine the precision for each type to keep things simple.

On with the show. I’ll do one, you do the rest. You will need one for each available answer.

(if (= answ “S”)(setq typ 1 prec 3));_end if Scientific ß-- this is a note.
What you just said was "if the answer to the question is “S”, set the variable typ to 1 and the variable prec to 3" or whatever precision you choose.

Now create the other if statements, one for each type you want.

Now we have three things to do.
1. Replace the existing numbers in the code with our new variables
(rtos ArcLength 5 5) becomes (rtos ArcLength typ prec)

2. Find a place to put all of the cool code we created at the beginning. Looking at the code, contributor D was anticipating user error, like any good programmer should. You will find a spot right after it asks you to “Select an Arc” that double checks the selection to be an “ARC”. If the object is an ARC, it processes the next lines of code. If not, it bypasses them and goes to a message “This ain’t no arc”. So we want our stuff to be in the part that only runs if the object is an arc. That is right after the lisp command (prong . Paste all that radical new code you created right after the (prong
(initget statment)
(prompt statment)
(if statments)

3. Kill your variable! As a good programmer, you give life and must take it away. Otherwise, your variable will get you when you least expect it. They have no respect for their creator and therefore must die when they are no longer needed.

To kill your variable, simply add them to the ones contributor D created
(defun c:dimarc ( / arclength center dimobj en endpoint obj startpoint)
The part of the code fragment above ( / arclength center dimobj en endpoint obj startpoint) is where you do this. Just add typ prec and answ to the end of the list
( / arclength center dimobj en endpoint obj startpoint typ prec answ)

Save your routine now!

Load it up and give it a spin, if it works. Great job! If it crashes your computer and it explodes into a billion pieces, I never met you and don’t have a clue what you're talking about.



From contributor D:
The third way might be just to replace the line
(cons 1 (rtos ArcLength 4 5))
with
(cons 1 (rtos ArcLength (getvar "LUNITS")(getvar "LUPREC")))
This should pick up your current unit settings.


From contributor J:
First of all, that would be way too easy and it would work in some cases. The precision of a dimension is not controlled by luprec and the type of dimstyle is not controlled by lunits, but you did hit the nail on the head.

The fourth and final way is to replace
(cons 1 (rtos ArcLength 4 5))
with
(cons 1 (rtos ArcLength (getvar "dimlunit")(getvar "dimdec")))

This will pick up your current dimension style settings.
Now all we have to do is get the questioner's suffix in there for fractions
(if (= (getvar "dimlunit") 5)(prong
(setq dimobj (entget (entlast))
dimobj (subst
(cons 1 (strcat(rtos ArcLength (getvar "dimlunit")(getvar "dimdec"))"\""));<-------
(assoc 1 dimobj)dimobj)))
(progn

(setq dimobj (entget (entlast))
dimobj (subst
(cons 1 (rtos ArcLength (getvar "dimlunit")(getvar "dimdec")));<-------
(assoc 1 dimobj)dimobj))))

place the above code between:
(command "_dimangular" en Center StartPoint EndPoint "\\")
and
(entmod dimobj))
Overwriting everything in between.



The comments below were added after this Forum discussion was archived as a Knowledge Base article (add your comment).

Comment from contributor A:
Here's a routine for changing the format of the dimension in AutoCAD. It does not change the value of the dimension, however it rounds off the dimension for fractions (3.758 becomes 3 ¾). Where fractional tolerance permits this is not a problem. Here's the routine, edit in notepad, saved as spdim.lsp:

(defun c:spdim()

(initget "F D")

(setq dse(getkword "Type: Dec/Frac"))

(if(= "F" dse)(setq ds 5))

(if(= "D" dse)(setq ds 2))

(setvar "dimlunit" ds)

(if(= 2 ds)(setvar "dimdec" 3))

(if(= 5 ds)(setvar "dimdec" 5))

)

Load the file into AutoCAD by:

Command: (load "spdim")

Here's a macro line in AutoCAD for the horiz dim:

^C^Cspdim;dim;hor;\\\\

It prompts you for F or D, you do a normal selection for dimensioning horizontal and the format comes out either as a stacked fraction or decimal.