Jump to content

odd behavior from autoLISP


ManiacalDigits

Recommended Posts

When I run this macro, the first time after loading it, it draws the first segment of the PLINE and chokes.   If I then delete the line it drew and re-run my macro it works as expected.  Can anyone help me understand why this happening?    Another occasional problem is that although p5 is set correctly the drawing is not correct.  

(defun C:FLATCALC () 

(SETQ COVERSTYLE (GETINT "\CoverStyle *  1-RECT  2-ROUNDED  3-CORNER (1-3) :"))

(SETQ MWIDTH (GETREAL "\Measured Width :"))
(SETQ MPROJ (GETREAL "\Measured Projection :"))

(if (= 1 COVERSTYLE) (SETQ RWIDTH MWIDTH))
(if (= 1 COVERSTYLE) (SETQ RPROJ MPROJ))
(if (= 1 COVERSTYLE) (SETQ RCHORD MWIDTH))
(if (= 1 COVERSTYLE) (SETQ MRAD 2))
(if (= 1 COVERSTYLE) (SETQ INSET 0))

(if (= 2 COVERSTYLE) (SETQ MCHORD (GETREAL "\Measured Chord :")))
(if (= 2 COVERSTYLE) (SETQ MRAD (GETREAL "\Measured Radius :")))
(if (= 2 COVERSTYLE) (SETQ RWIDTH (+ MWIDTH 1.5)))
(if (= 2 COVERSTYLE) (SETQ RPROJ (+ MPROJ 0.75)))
(if (= 2 COVERSTYLE) (SETQ RCHORD (+ MCHORD 1.5)))
(if (= 2 COVERSTYLE) (SETQ OFFSET (- MWIDTH MCHORD)))
(if (= 2 COVERSTYLE) (SETQ INSET (/ OFFSET 2)))

(if (= 3 COVERSTYLE) (SETQ CSIDE (GETINT "\Corner Side 1-LEFT  2 RIGHT  (1-2) :")))
(if (= 3 COVERSTYLE) (SETQ RWIDTH MWIDTH))
(if (= 3 COVERSTYLE) (SETQ RPROJ MPROJ))
(if (= 3 COVERSTYLE) (SETQ RCHORD MWIDTH))
(if (= 3 COVERSTYLE) (SETQ INSET 0))


(SETQ p0 (list 0 0))
(SETQ p1 (list 0 RWIDTH))
(SETQ p2 (list (- RPROJ MRAD) (- RWIDTH INSET)))
(SETQ p3 (list RPROJ (- RWIDTH (+ MRAD INSET))))
(SETQ p4 (list RPROJ (+ MRAD INSET)))
(SETQ p5 (list (- RPROJ MRAD) INSET))
(setq c1 (list 48.125 RWIDTH))


(command "_pline" p0 p1 p2 p3 p4 p5 "C")
(setvar "filletrad" MRAD)
  
;(setq RRAD MRAD)
;(if (= 3 COVERSTYLE) (if (= CSIDE 1) (SETQ RRAD 1)))
;(setvar "filletrad" RRAD)
  
(command "_fillet" p2 p4)

;(setq LRAD MRAD)
;(if (= 3 COVERSTYLE) (if (= CSIDE 2) (SETQ LRAD 1)))
;(setvar "filletrad" LRAD)

(command "_fillet" p4 p0)

(if (< RPROJ 48) (command "_line" p1 c1 ""))

(princ)
  
)




 

I am also trying to set the thickness of both the PLINE and LINE.   This is proving quite frustrating.  Any help is appreciated!   TIA

Link to comment
Share on other sites

Just basic trouble shooting - CAD is off for the evening here - you might want to localise the variables that you can.

 

If a variable that you are using is only used in this LISP copy its name in the defun line something like:

 

defun C:FLATCALC ( / COVERSTYLE MWIDTH MPROJ ..... 

 

after the / for any variables used only here. It might be that the LISP is picking up something left over from another LISP.

 

Second thing to look for do you refer to a variable earlier in the LISP before you asign a value to it? Without local variables then when you first run the LISP it might set a value which is remembered for the subsequent times you run it:

 

 

For example:

 

 

(defun c:example ( / )

  (setq A_Length New_Length)  ;; this value depends on another set later in the lisp
  (setq New_length 5)         ;; set the new value
  (setq Another_Length (* 2 A_Length)) ;; do something with the frst value that is 'nil' the first time the LISP runs
  
)

 

  • Agree 1
Link to comment
Share on other sites

If the user selects option 3, what is the value of MRAD? You use it to calculate p2, p3, p4, and p5. Once you run option 1 or 2, it gets a value, but that value is arbitrary when you run option 3.

 

There are some redundant statements. For instance, you could set RWIDTH to MWIDTH by default, which covers options 1 and 3, and change it for option 2. Then again, I'm not sure what function RWIDTH serves, couldn't you just refer to MWIDTH?

  • Agree 1
Link to comment
Share on other sites

Just a suggestion code wise

 

(if (= 1 COVERSTYLE) (SETQ RWIDTH MWIDTH))
(if (= 1 COVERSTYLE) (SETQ RPROJ MPROJ))
(if (= 1 COVERSTYLE) (SETQ RCHORD MWIDTH))
(if (= 1 COVERSTYLE) (SETQ MRAD 2))
(if (= 1 COVERSTYLE) (SETQ INSET 0))

(if (= 1 COVERSTYLE) 
(progn
  (SETQ RWIDTH MWIDTH))
  (SETQ RPROJ MPROJ))
  (SETQ RCHORD MWIDTH))
  (SETQ MRAD 2))
  (SETQ INSET 0)
)
)

(if (= 1 COVERSTYLE) 
  (SETQ RWIDTH MWIDTH RPROJ MPROJ RCHORD MWIDTH MRAD INSET 0)
)

 

Similar using a (Cond

Link to comment
Share on other sites

Thanks for the quick replies!

 

@Steven P  that may very well resolve the issue, I'll try it first thing in the morning.  I am actually using an AutoCAD supplied by Router-CIM and yeah, they have a TON of stuff going on that I dont fully understand.  A good topic to discuss next time I train with them.  Because I hope to do everything under this one macro I can't imagine why I wouldn't localize all my variables.  Thanks for the tip.

@CyberAngel @BIGAL option 3 needs two different radii... depending on which side.  Please forgive my childlike coding here :)  really new to LISP and just trying to keep it strait in my head.   First time I've dealt with reverse polish notation and nesting as well.  The reason for all the variables is I'm asking the user for real measurements and then option 2 requires a little tweaking.  1 and 3 can be the real measurments, thats true.

 

I hope to rewrite and optimize after I get it working right.... sooo close :)   Any suggestions on setting the thickness property?   Seems easier to do it by hand than ref an Object/Entity! lol

 

Thanks!

 

Link to comment
Share on other sites

Looking again I think you need MRAD in option 3, 

 

Added in localised variables, changed the if statements a little so they are as a group (bounded by 'progn' for each state of the if statement) and added a setq MRAD and it seams to complete the LISP.

 

For thickness property, are you thinking about polyline width or  Z plane thickness? If you can upload a drawing with what you are trying to make up am sure we can help out

 

 

(defun C:FLATCALC ( / COVERSTYLE MWIDTH MPROJ RWIDTH RPROJ MCHORD RCHORD MRAD INSET OFFSET CSIDE )

  (SETQ COVERSTYLE (GETINT "\CoverStyle *  1-RECT  2-ROUNDED  3-CORNER (1-3) :"))

  (SETQ MWIDTH (GETREAL "\Measured Width :"))
  (SETQ MPROJ  (GETREAL "\Measured Projection :"))

  (if (= 1 COVERSTYLE)
    (progn 
      (SETQ RWIDTH MWIDTH)
      (SETQ RPROJ MPROJ)
      (SETQ RCHORD MWIDTH)
      (SETQ MRAD 2)
      (SETQ INSET 0)
    ) ; END PROGN
  ) ; END IF

  (if (= 2 COVERSTYLE)
    (progn
      (SETQ MCHORD (GETREAL "\Measured Chord :"))
      (SETQ MRAD (GETREAL "\Measured Radius :"))
      (SETQ RWIDTH (+ MWIDTH 1.5))
      (SETQ RPROJ (+ MPROJ 0.75))
      (SETQ RCHORD (+ MCHORD 1.5))
      (SETQ OFFSET (- MWIDTH MCHORD))
      (SETQ INSET (/ OFFSET 2))
    ) ; end progn
  ) ; end if

  (if (= 3 COVERSTYLE)
    (progn
      (SETQ CSIDE (GETINT "\Corner Side 1-LEFT  2 RIGHT  (1-2) :"))

      (SETQ MRAD (GETREAL "\Measured Radius :")) ;; ADDED THIS HERE TO MAKE IT WORK

      (SETQ RWIDTH MWIDTH)
      (SETQ RPROJ MPROJ)
      (SETQ RCHORD MWIDTH)
      (SETQ INSET 0)
    ) ; end progn
  ) ; end if

  (SETQ p0 (list 0 0))
  (SETQ p1 (list 0 RWIDTH))
  (SETQ p2 (list (- RPROJ MRAD) (- RWIDTH INSET))) ;;MRAD NOT SET OPTION 3
  (SETQ p3 (list RPROJ (- RWIDTH (+ MRAD INSET)))) ;;MRAD NOT SET OPTION 3
  (SETQ p4 (list RPROJ (+ MRAD INSET)))            ;;MRAD NOT SET OPTION 3
  (SETQ p5 (list (- RPROJ MRAD) INSET))            ;;MRAD NOT SET OPTION 3
  (SETQ c1 (list 48.125 RWIDTH))

  (command "_pline" p0 p1 p2 p3 p4 p5 "C")
  (setq Filletrad_Old (getvar "filletrad"))
  (setvar "filletrad" MRAD)
  
;;  (setq RRAD MRAD)
;;  (if (= 3 COVERSTYLE) (if (= CSIDE 1) (SETQ RRAD 1)))
;;  (setvar "filletrad" RRAD)
  
  (command "_fillet" p2 p4)

;;  (setq LRAD MRAD)
;;  (if (= 3 COVERSTYLE) (if (= CSIDE 2) (SETQ LRAD 1)))
;;  (setvar "filletrad" LRAD)

  (command "_fillet" p4 p0)

  (setvar "filletrad" Filletrad_Old) ; reset filletrad to as it was

  (if (< RPROJ 48) (command "_line" p1 c1 ""))
  (princ)
  
)

 

Link to comment
Share on other sites

a few tweaks

 

getkword will allow you to type in a better response instead of numbers. So typeing "C" will pick corner or "Rou" will pick Round. hitting enter (not selecting an option) will default to the Rect.

also using getdist instead of getreal still allows you to type in a distance but if you want you have to option of picking two points with a mouse.

 

Allows you to either type FC or FLATCALC to run the command.

My 0.02¢ stop juggling variables. use the condition function then inside calculate the points for each style and even draw the polylines. This will get you close using P1 as an example

(defun C:FLATCALC () (FC))
(defun C:FC (/ Style Wid Pro P0 P1 P2 P3 P4 P5 C1)
  (initget "Rect Round Corner")
  (setq Style
    (cond
      ((getkword "\nCoverStyle [<Rect> Round Corner]: ")) ("Rect") ;defaults to rect responce
    )
  )
  (setq Wid (getdist "\nMeasured Width :"))  ;either input with keyboard or use mouse to pick points 
  (setq Pro (getdist "\nMeasured Projection :"))
  (setq P0 '(0 0))
  (cond 
    ((= "Rect" Style)
      ;add code here to calultate points for this style
      (setq P1 (list 0 Wid))
      ;then draw the polyline
    )
    ((= "Round" Style)
      (setq chord (getdist "\nMeasured Chord :"))  ;\n is newline to command line
      (setq mrad (getdist "\nMeasured Radius :"))
      ;add code here to calultate points for this style
      (setq P1 (list 0 (+ Wid 1.5))
      ;then draw the polyline
      ;use fillet commands
    )
    ((= "Corner" Style)
      ;add code here to calultate points for this style
      (setq P1 (list 0 Wid))
      ;then draw the polyline
      (command "_pline" p0 p1 "C") 
    )
  )

  (princ)
)

 

 

 

 

 

 

Edited by mhupp
  • Like 2
Link to comment
Share on other sites

I dont use initget any more I think I have provided you with the library function "Multi radio buttons.lsp" just find much easier for users to select rather than type. Like wise 2 lines of code to use it.

Multi radio buttons.lsp

Edited by BIGAL
  • Like 1
Link to comment
Share on other sites

13 hours ago, Steven P said:

changed the if statements a little so they are as a group (bounded by 'progn' for each state of the if statement)

 

Is it considered poor form to consolidate SETQ statements? Like so

 

(setq
	A 5
	B 2
	C 13)

 

Link to comment
Share on other sites

It depends.....

 

I tend to separate them here on the forum, it is easier to see what is happening that way which is good for learning.

 

I don't think it makes a noticeable speed difference either way

 

But it has uses, for example can group things together this example uses progn, or not

 

(if (= AThing Somthing)
  (progn
    (setq One 1)
    (setq Two 2)
    (setq Three 3)
  ) ; end progn
) ; end if

 

(if (= AThing Somthing)
  (setq One 1
    Two 2
    Three 3
  ) ; end setq
) ; end if

 

  • Like 1
Link to comment
Share on other sites

6 minutes ago, CyberAngel said:

Is it considered poor form to consolidate SETQ statements? Like so

 

I don't think so you could even do it like this.

(setq A 5 B 2 C 13)

 

Its just what ever your comfortable with making it easier to read/edit. might be hard to pick up that B is being set to 2 but if its called out with its own setq then it might be a little easier to follow.

  • Like 1
Link to comment
Share on other sites

please keep going.... i'm listening!   got snowed in but am about to get my hardware key from the shop and do this from home if I need to.    feel like i stumbled onto a gold mine here!

@Steven P  well thought out and thank you, I'm going to try your version as soon as I can.  I am trying to set the z plane thickness in the properties for the drawings this macro makes.

 

Edited by ManiacalDigits
  • Like 1
Link to comment
Share on other sites

when I am testing this code I like to start with option 2 ( the whole reason I started this ) and use 62 for the width, 40 for the projection, 58 for the chord and 15 for the radius.   this usually works and shows what I am looking for.   for coverstyle 1 i use something like 88 width and 40 projection.   Corners are a bit of a problem.   I already know the radius I want to use but need to know which side gets a 1" and which side gets a 2".  2" is my standard radius.   option 2 is the only one that needs to be something different.

Link to comment
Share on other sites

@Steven P  I finally had a chance to try your re-write and it seems to work right the first time everytime so far.  Thank you for helping me understand!

 

And thanks to everyone who looked at this and helped!  Next time I'm stumped I will come here first.

  • Like 1
Link to comment
Share on other sites

I really thought this was fixed.  When I left last night this was working perfectly. 

 

(defun C:FLATCALC ( / COVERSTYLE MWIDTH MPROJ RWIDTH RPROJ MCHORD RCHORD MRAD INSET OFFSET CSIDE)

  (SETQ COVERSTYLE (GETINT "\CoverStyle *  1-RECT  2-ROUNDED  3-CORNER (1-3) :"))

  (SETQ MWIDTH (GETREAL "\Measured Width :"))
  (SETQ MPROJ  (GETREAL "\Measured Projection :"))

  (if (= 1 COVERSTYLE)
    (progn 
      (SETQ RWIDTH MWIDTH)
      (SETQ RPROJ MPROJ)
      (SETQ RCHORD MWIDTH)
      (SETQ MRAD 2)
      (SETQ INSET 0)
    ) ; END PROGN
  ) ; END IF

  (if (= 2 COVERSTYLE)
    (progn
      (SETQ MCHORD (GETREAL "\Measured Chord :"))
      (SETQ MRAD (GETREAL "\Measured Radius :"))
      (SETQ RWIDTH (+ MWIDTH 1.5))
      (SETQ RPROJ (+ MPROJ 0.75))
      (SETQ RCHORD (+ MCHORD 1.5))
      (SETQ OFFSET (- MWIDTH MCHORD))
      (SETQ INSET (/ OFFSET 2))
    ) ; end progn
  ) ; end if

  (if (= 3 COVERSTYLE)
    (progn
      (SETQ CSIDE (GETINT "\Corner Side 1-LEFT  2 RIGHT  (1-2) :"))
      (SETQ MRAD 2) ;; ADDED THIS HERE TO MAKE IT WORK
      (SETQ RWIDTH MWIDTH)
      (SETQ RPROJ MPROJ)
      (SETQ RCHORD MWIDTH)
      (SETQ INSET 0)
    ) ; end progn
  ) ; end if

  (SETQ myPnt0 (list 0 0))
  (SETQ myPnt1 (list 0 RWIDTH))
  (SETQ myPnt2 (list (- RPROJ MRAD) (- RWIDTH INSET))) 
  (SETQ myPnt3 (list RPROJ (- RWIDTH (+ MRAD INSET)))) 
  (SETQ myPnt4 (list RPROJ (+ MRAD INSET)))           
  (SETQ myPnt5 (list (- RPROJ MRAD) INSET))           
  (SETQ coPnt1 (list 48.125 RWIDTH))

  (command "_pline" myPnt0 myPnt1 myPnt2 myPnt3 myPnt4 myPnt5 "C")
  (setvar "filletrad" MRAD)
  (command "_fillet" myPnt2 myPnt4 "_fillet" myPnt4 myPnt0)

  (if (/= CSIDE nil)
	(progn
          (setvar "filletrad" 1)
	  (if (= CSIDE 1) (command "_fillet" myPnt4 myPnt0) (command "_fillet" myPnt2 myPnt4))
	     
	) 
    )

  (if (< RPROJ 48) (command "_line" myPnt1 coPnt1 ""))
  (princ)
  
)

 

when I ran the thing this morning I'm back to an error on first run

 

*Invalid selection*
Expects a point or Window/Last/Crossing/BOX/Fence/WPolygon/CPolygon/uNdo/Polyline/Radius/Trim
Function cancelled

 

run it again and it works, sort of...  the thing that is blowing me away here is that the polyline is not being drawn correctly at myPnt4 and myPnt5 and an inspection of the values shows they are correct.  the attached file shows this. 

 

just to further confuse myself I then run what SteveP  wrote and it works fine.  then I run mine and it works fine.  this behavior is making me bald.

fail.dwg

Link to comment
Share on other sites

ah ha!!   o-snaps.   turning that off seems to fix both problems.

 

ok, so this is working now.  

 

The attached file is an example of this macros output.   I am still trying to figure out how to set the z-plane thickness within this macro.

 

Any ideas?

set_thickness.dwg

Link to comment
Share on other sites

OK here is a little tip, it isn't documented so well:

 

(command "_pline" myPnt0 "_non" myPnt1 "_non" myPnt2 "_non" myPnt3 "_non" myPnt4 "_non" myPnt5 "_non" "C")

 

The "_non" should temporarily suspend object snaps for the point just before it - handy that you can draw lines in a LISP without modifying the users settings and returning them again (which in the event of the user cancelling or other errors, will could result in an unexpected setting change for the user).

 

 

Once you get this working consistently ask again about entmake entities - a little quicker to run than say (command "PLINE"....) (tiny amount) but doesn't have the problem of snaps

Link to comment
Share on other sites

@Steven P the "_non" modifier should be used BEFORE the point to disable the object snap, not after it. Try it at the command line.

Edited by pkenewell
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...