Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AutoLISP Routine Help - Going Insane.

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
bennywise578
676 Views, 9 Replies

AutoLISP Routine Help - Going Insane.

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.

9 REPLIES 9
Message 2 of 10
Kent1Cooper
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, AIA
Message 3 of 10
bennywise578
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.

Message 4 of 10
jdvillarreal
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.

Message 5 of 10
bennywise578
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.

Message 6 of 10


@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.

 

--


 

Message 7 of 10
jdvillarreal
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.

Message 8 of 10
dgorsman
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.
"I don't know" is the beginning of knowledge, not the end.


Message 9 of 10
jdvillarreal
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.

Message 10 of 10
bennywise578
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!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost