TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: AWW on January 12, 2010, 12:13:44 PM

Title: DIMASZ Variable...
Post by: AWW on January 12, 2010, 12:13:44 PM
Via AutoCAD 2008 Help:

Controls the size of dimension line and leader line arrowheads. Also controls the size of hook lines.

I'm focusing on the hook lines with this code:

(setq land (* (getvar "dimasz") (getvar "dimscale")))

Trying to get pt2 and add the landing gap automatically:

(setq pt3 (+ (getpoint pt2 (* (getvar "dimasz") (getvar "dimscale")))

or

(setq pt3 (+ (getpoint pt2) (land))

I can't be that far off, but it seems everything I try is off. I know how
to get autocad defined variables with getvar. Does that also work for the ones
that are created manually? What am I missing?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 12, 2010, 12:38:59 PM
You want to look into the polar function

GetPoint is for prompting the user for a point selection  :wink:
Title: Re: DIMASZ Variable...
Post by: Crank on January 12, 2010, 01:06:47 PM
What am I missing?
1) Only the first line of lisp will work
2) You are trying to add a distance to coordinates.

If you just want a angle of 90 degrees, your code would be something like:
Code: [Select]
(setq p2 (getpoint))
(setq p3 (list (car p2)(+ (cadr p2) land)))
You can improve this with the use of the functions POLAR and TRANS.

(getvar "DIMSCALE") worked fine until Acad2008. Because that release also offers annotative scaling, it's better to replace this with a function that handles the scale:
Code: [Select]
(defun b=sch ()
(if (and (zerop (getvar "TILEMODE"))(zerop (getvar "VPMAXIMIZEDSTATE"))(eq (getvar "CVPORT") 1))
1.0
; else
(progn
(if (zerop (getvar "DIMANNO"))
(if (zerop (getvar "DIMSCALE")) 1.0 (getvar "DIMSCALE"))
(/ 1.0 (getvar "CANNOSCALEVALUE"))
)
)
)
)
If your dimstyle is annotative, this will use the annoscale, if it's not annotative it will still use the DIMSCALE.

If you have 2008 I wouldn't use the old leaders any more, because Mleaders are much better.
Title: Re: DIMASZ Variable...
Post by: AWW on January 12, 2010, 01:50:55 PM
LeeMac: I realized that at about the getpoint. I thought the getpoint could actually just get a point without user input as 
            well. Guess I get mixed up about what to use sometimes.  :oops:

Crank: I did not know that about dimscale in 2008. Thanks for todays lesson! lol
Title: Re: DIMASZ Variable...
Post by: Krushert on January 12, 2010, 09:45:21 PM

(getvar "DIMSCALE") worked fine until Acad2008. Because that release also offers annotative scaling, it's better to replace this with a function that handles the scale:
Code: [Select]
(defun b=sch ()
(if (and (zerop (getvar "TILEMODE"))(zerop (getvar "VPMAXIMIZEDSTATE"))(eq (getvar "CVPORT") 1))
1.0
; else
(progn
(if (zerop (getvar "DIMANNO"))
(if (zerop (getvar "DIMSCALE")) 1.0 (getvar "DIMSCALE"))
(/ 1.0 (getvar "CANNOSCALEVALUE"))
)
)
)
)
If your dimstyle is annotative, this will use the annoscale, if it's not annotative it will still use the DIMSCALE.


Interesting Crank.  I will have to give that one some thought
Title: Re: DIMASZ Variable...
Post by: AWW on January 26, 2010, 01:02:52 PM
I've been flirting with this landing, trying to get it to work properly. I had thought about using polar, but the more I thought about it, the more I realized that the landing isn't always going to be 90 degress. The angle isn't what I am after, it's the horizontal landing line to the left or to the right, whatever angle it may turn out to be.

Right now I'm using:

(setq pt3 (list (car pt2)(+ (cadr pt2) land)))

But when I get to:

(setq mtxtobj (vla-addmtext mspace (vlax-3d-point pt3) 0 ""))
(setq ldrObj (vlax-invoke-method mspace 'addleader ptlist mtxtobj acLineWithArrow))

I seem to get errors about a variant and safearrays, which I haven't used. Instead, I used:

(setq ptlist (apply 'append (list pt1 pt2 pt3)))

Any suggestions?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 26, 2010, 03:56:08 PM
The "points array" argument in the addleader method needs to be a variant.

Something like:

Code: [Select]
(setq ptLst (apply (function append) (list pt1 pt2 pt3)))

(vlax-make-variant
  (vlax-safearray-fill
    (vlax-make-safearray vlax-vbDouble
      (cons 0 (1- (length ptLst)))) ptLst))
Title: Re: DIMASZ Variable...
Post by: AWW on January 27, 2010, 08:18:29 AM
Thanks Lee. One question... the function can be any function in (function append)?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 27, 2010, 08:19:48 AM
Thanks Lee. One question... the function can be any function in (function append)?

Sorry, not sure what you mean? Function is an AutoLISP function in itself  :-)
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 27, 2010, 09:31:26 AM
That is what I meant, any autocad funtion. I have only seen mapcar and lambda used there.

No, 'function' is a function in AutoLISP - look it up in the VLIDE help files  :wink:  It declares 'append' as a function.

Title: Re: DIMASZ Variable...
Post by: AWW on January 27, 2010, 09:37:46 AM
Ok. I see. Is it still Monday?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 27, 2010, 10:05:33 AM
Ok. I see. Is it still Monday?

 :-D
Title: Re: DIMASZ Variable...
Post by: AWW on January 27, 2010, 10:10:48 AM
The reason I asked was that I seem to get:

error: Upper bound in SAFEARRAYBOUND occurred to be less
than lower.

What does that mean?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 27, 2010, 10:27:30 AM
That would occur if (length ptLst) = 0.
Title: Re: DIMASZ Variable...
Post by: AWW on January 27, 2010, 11:37:36 AM
Ok. I got the above code to work. But it doesn't seem to recognize it for some reason when I get here:

  (setq mtxtobj (vla-addmtext mspace (vlax-3d-point pt3) 0 ""))
  (setq ldrObj (vlax-invoke-method mspace 'addleader ptLst mtxtobj acLineWithArrow))
  (vla-delete mtxtobj)

I get this: lisp value has no coercion to VARIANT with this
type:  (2231.13 1060.76 0.0 2293.22 1183.58 0.0 2293.22 1188.58)

Just by looking at this, it seems like the last point (pt3) is a 2d point instead of a 3d point. Correct?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 27, 2010, 11:47:12 AM
The ptLst needs to be a variant, as stated earlier.

i.e.

Code: [Select]
(setq mtxtobj (vla-addmtext mspace (vlax-3d-point pt3) 0 ""))
(setq ptLst   (apply (function append) (list pt1 pt2 pt3)))

(setq ldrObj (vlax-invoke-method mspace 'addleader (vlax-make-variant
                                                     (vlax-safearray-fill
                                                       (vlax-make-safearray vlax-vbDouble
                                                         (cons 0 (1- (length ptLst)))) ptLst))
               mtxtobj acLineWithArrow))

(vla-delete mtxtobj)

Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 27, 2010, 03:33:32 PM
This should help you:

Code: [Select]
(defun leader (pts txt typ / spc)
  (setq doc (cond (doc) ((vla-get-ActiveDocument
                           (vlax-get-acad-object))))

        spc (if (zerop (vla-get-ActiveSpace doc))
               (vla-get-PaperSpace doc)
               (vla-get-ModelSpace doc)))

  (cond (  (< (length pts) 2))
       
        (  (vlax-invoke-method spc 'AddLeader
             (vlax-make-variant
               (vlax-safearray-fill
                 (vlax-make-safearray vlax-vbDouble
                   (cons 0 (1- (* 3 (length pts)))))
                 (apply (function append) pts)))

              (vlax-invoke-method spc 'AddMText
                (vlax-3D-point (last pts)) 0. txt) typ))))



(defun c:test (/ ptLst pt)
  (vl-load-com)

  (if (car (setq ptLst (list (getpoint "\nFirst Point of Leader: "))))
    (progn
      (while (setq pt (getpoint (car ptLst) "\nNext Point: "))
        (setq ptLst (cons pt ptLst)))

      (leader (reverse ptLst) "Lee Mac" acLineWithArrow)))

  (princ))
Title: Re: DIMASZ Variable...
Post by: AWW on January 28, 2010, 09:06:04 AM
error: Automation Error. Too few elements in SafeArray
or total number of elements is not a multiple of three

I think this is my pt3:

(setq pt3 (list (car pt2)(+ (cadr pt2) land)))

where land is:

(setq land (* (getvar "dimasz") (getvar "dimscale"))) ;;;Hook Line size

I think it is getting a 2D point when I need a 3D point. I looked at the leader object in the help files for something like the dogleg for mleaders. The only thing I could find that was possible was:

vlax-3d-point

But I am unsure how to incorporate this together...
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 28, 2010, 10:27:06 AM
Code: [Select]
(setq pt3 (list (car pt2)(+ (cadr pt2) land)))
Is 2D.

Code: [Select]
(setq pt3 (list (car pt2) (+ (cadr pt2) land) 0.0))
Is now 3D.

The PointsArray argument is as follows:

Quote
Variant (array of doubles); input-only
The array of 3D WCS coordinates specifying the leader.

Also, see my example above.  :-)
Title: Re: DIMASZ Variable...
Post by: AWW on January 28, 2010, 04:16:19 PM
Thanks Lee. I was thinking it had to be more complex than that.  :-o As a general rule of thumb, can any two functions be combined to accomplish a task?

For example:

(setq pt3 (list (car pt2)(+ (cadr pt2) land) 0.0))

which makes the landing.

In order to make that landing always horizontal, I could just add the polar funtion to it?

I've seen quite a few lisp that you have written, and quite impressive. They have good structure to them. Is there a certain structure to go about writing them?
Title: Re: DIMASZ Variable...
Post by: Lee Mac on January 28, 2010, 07:53:09 PM
Thanks Lee. I was thinking it had to be more complex than that.  :-o As a general rule of thumb, can any two functions be combined to accomplish a task?

For example:

(setq pt3 (list (car pt2)(+ (cadr pt2) land) 0.0))

which makes the landing.

In order to make that landing always horizontal, I could just add the polar funtion to it?

I've seen quite a few lisp that you have written, and quite impressive. They have good structure to them. Is there a certain structure to go about writing them?

Thanks AWW,

I tend to group my code into parts that are performing each task in turn, instead of having just one long list - it is easier to read that way.  :wink:

As for using polar, I you can combine as many LISP functions as you like, LISP is interpreted from the "inside-out"; but in my opinion, I would either use a point defined using the polar function, or define it manually using each cartesian coordinate, else things get complicated.

Lee