Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Active Contributor
bennywise578
Posts: 32
Registered: ‎10-27-2011
Message 1 of 10 (444 Views)
Accepted Solution

AutoLISP Routine Help - Going Insane.

444 Views, 9 Replies
10-27-2011 06:19 AM

Hey,

 

I'm trying to essentially make a mini frame generator in autolisp. Namely a function where one can enter the width, height, thickness, how many bays, how many day light openings, and then autocad draws the frame. Right now I'm just trying to get two settings to work with each other - and upon opening autocad the function works initially but then when I try to switch to the other setting it does not work. I felt like this was a global/local variable issue, but I cannot figure it out for the life of me. I have attached the segment of the code I have been working on and trying to debug the situation. Any help would be greatly appreciated. Thanks.

Hey everyone,

 

I finished the code and it works well. My code definitely could be improved and shortened, but unfortunately I am too stubborn and HAD to finish it the way I was doing it. I attached my final code as of now. Co-workers are quite pleased. Thanks again to everyone!

*Expert Elite*
Kent1Cooper
Posts: 5,879
Registered: ‎09-13-2004
Message 2 of 10 (428 Views)

Re: AutoLISP Routine Help - Going Insane.

10-27-2011 07:44 AM in reply to: bennywise578

bennywise578 wrote:

.... 

I'm trying to essentially make a mini frame generator in autolisp. .... Right now I'm just trying to get two settings to work with each other - and upon opening autocad the function works initially but then when I try to switch to the other setting it does not work. ....


What do you mean by "switch to the other setting"?  What are the "two settings" you're trying to get to work with each other?

 

I think you could shorten it a lot by using (set) instead of (setq) and constructing variable names with (read (strcat ...)), in a manner something like this:

 

(defun var (typ); = build VARiable name with type and current integer ending
  (read (strcat typ (itoa inc)))
); defun

 

(defun ev (typ); = Get what's in the above variable
  (eval (read (strcat typ (itoa inc))))
); defun

 

You would start a counter [the 'inc' variable in the above], and do this:

 

(set (var "dlo") (getdist (strcat "\nDLO Height " (itoa inc) ": ")))

 

When the counter is 1, that will prompt for "DLO Height 1: " and set the specified distance into the dlo1 variable.  Step the counter up to 2, and it will next do the same with dlo2, and you can go on for as long as you want.  You don't need to build all the prompts for all those values separately, with separate lists of prompts for each possible quantity, nor do you have any limitation on how many.

 

You would set values for bay widths similarly with:
 

(set (var "b") (getdist (strcat "\nBay width " (itoa inc) ": ")))

 

EDIT:

To be more specific:  After you've gotten the bays quantity [without the maximum of 10] from the User, you can do this:

 

(setq inc 1)

(repeat bays

  (set

    (var "b")

    (getdist (strcat "\nBay width " (itoa inc) ": "))

  ); set

  (setq inc (1+ inc))

); repeat

 

and that will get all the bay widths from the User, no matter how many they call for.

end EDIT

 

Then when doing the drawing, reset the counter to 1, and when you use

 

(ev "dlo")

 

it will return the value in the dlo1 variable,

 

(ev "b")

 

will return the value in the b1 variable, and as you step the counter up you'll get the values in dlo2 and b2, etc.

 

[In case you ever do this with all bay sizes equal, you might have a use for the PanelDivRect.lsp routine at the end of this thread:

 

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Simple-problems-with-my-divide-panels...

 

It has some differences (e.g. it asks for the overall outside dimensions to divide equally, rather than the sizes of the bays), but it's not limited in the number of bays in either direction, and has some other nice features.]

Kent Cooper
Active Contributor
bennywise578
Posts: 32
Registered: ‎10-27-2011
Message 3 of 10 (391 Views)

Re: AutoLISP Routine Help - Going Insane.

10-27-2011 02:25 PM in reply to: Kent1Cooper

This is what I have so far now. Firstly, thanks for your previous post, this helped me shorten it a great deal as well as improve my knowledge of autolisp in general. Right now I'm running into problems getting the top and bottom lines to go all the way across the "frame wall" (they seem to be connecting to a previously placed wall) as well as getting the horizontals to move over to the next bay. (it's tough for me to explain, but I have marked out the areas in my code where I am having problems). If you get a chance, let me know if you have any suggestions or solutions. You've already been a huge help. Thanks again.

Active Contributor
jdvillarreal
Posts: 26
Registered: ‎04-02-2009
Message 4 of 10 (376 Views)

Re: AutoLISP Routine Help - Going Insane.

10-27-2011 04:09 PM in reply to: bennywise578

I think y'all are overthinking this one.

Consider using lists...You would construct a list of the heights and widths which you could then accumulate to array your lines.

Example:

(while (not (<= 1 bays 10))
(setq bays (cond ((getint "\n# of bays [1 - 10] <1>: "))(t 1)))
(if (or (< bays 1)(> bays 10))(princ "\nInvalid entry. Try again."))
)
(setq inc 0 baylist (list st))
(repeat bays
  (setq baylist (append baylist (list (getdist (strcat "\nBay " (itoa (setq inc (1+ inc))) " Width:")) st))))

 

I've attached the updated lisp for you to compare your result.

Active Contributor
bennywise578
Posts: 32
Registered: ‎10-27-2011
Message 5 of 10 (345 Views)

Re: AutoLISP Routine Help - Going Insane.

10-28-2011 04:51 AM in reply to: bennywise578

I'm still going through your code. However, I get this error when I try to run your code:

 

Command: cw1
; error: no function definition: VLAX-GET-ACAD-OBJECT

 

EDIT:

 

If you could explain how your accum function works and the vla/vlax commands you have added in that would also help out a lot.  Thanks.

Valued Mentor
martti.halminen
Posts: 349
Registered: ‎12-31-2009
Message 6 of 10 (337 Views)

Re: AutoLISP Routine Help - Going Insane.

10-28-2011 05:56 AM in reply to: bennywise578

bennywise578 wrote:

I'm still going through your code. However, I get this error when I try to run your code:

 

Command: cw1
; error: no function definition: VLAX-GET-ACAD-OBJECT

 


This is just a problem of missing a call to VL-LOAD-COM before using VLA- functions.

 

Your original program has at leat this major problem:

 

(cond (and (= dlos 4) (= bays 4) ;****

 

- and several others like this. Here are two separate errors:

1. The key  to choose whether to run a particular branch is the value of the first item in the list.

In this case that is #<SUBR @17cc4b2c AND>, which is always non-nil.

 You should have (cond ((and (....

2. Where is the closing paren for the AND expression?

 

- Generally, the original version is not worth saving, just collect a list of heights and list of widths, and loop through those drawing rectangles as required. No dozens of variables needed.

 

--


 

Active Contributor
jdvillarreal
Posts: 26
Registered: ‎04-02-2009
Message 7 of 10 (329 Views)

Re: AutoLISP Routine Help - Going Insane.

10-28-2011 06:38 AM in reply to: bennywise578

Sorry, i have other routines that contain (vl-load-com) already, so i forgot to include it in your code.

 

The accum function works by placing the total in a new list, removing the last item of the original list and repeating..

resulting in a list of the accumulated numbers.

Ex: ( 5 1 5 2 5) -> (5 6 11 13 18)

(defun accum (wlist / cw1wlist)
 (repeat (length wlist)
  (setq cw1wlist (cons (apply '+ wlist) cw1wlist);<-place total of given list
        wlist (reverse (cdr (reverse wlist))));<-remove last item of given list
 )
 cw1wlist;<-output resulting list
)

 

The developer documentation will explain the vla/vlax stuff. ArrayRectangular, AddLine, vlax-3d-point.

*Expert Elite*
dgorsman
Posts: 5,698
Registered: ‎10-12-2006
Message 8 of 10 (315 Views)

Re: AutoLISP Routine Help - Going Insane.

10-28-2011 07:57 AM in reply to: jdvillarreal

Instead of repeatedly reversing the list to pull off the last element, try constructing the list in reverse order then working on the (car...)/first element of the list.  To "pull it off" set the list variable to the (cdr...) of the list.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
Adopt. Adapt. Overcome. Or be overcome.
A good question will be halfway to a good answer.


Active Contributor
jdvillarreal
Posts: 26
Registered: ‎04-02-2009
Message 9 of 10 (309 Views)

Re: AutoLISP Routine Help - Going Insane.

10-28-2011 08:57 AM in reply to: dgorsman

Thanks for the suggestion. The code actually has several places that could use improvement but was done quickly as an example of the concept. Let us know how you get along with your code bennywise.

Active Contributor
bennywise578
Posts: 32
Registered: ‎10-27-2011
Message 10 of 10 (306 Views)

Re: AutoLISP Routine Help - Going Insane.

10-28-2011 09:01 AM in reply to: jdvillarreal

Hey everyone,

 

I finished the code and it works well. My code definitely could be improved and shortened, but unfortunately I am too stubborn and HAD to finish it the way I was doing it. I attached my final code as of now. Co-workers are quite pleased. Thanks again to everyone!

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.