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

Cobbled together lisp routine

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
LDShaw
906 Views, 7 Replies

Cobbled together lisp routine

I am hoping you all can help me. I hope this is at least halfway coherent. I've been working on it for so long I may assume parts you don't know. I have added a streamcast to give you an example of what I am trying to do.

I have a cobbled together lisp routine and while it works it’s a long way from elegant. What I want it to do is decide whether it needs the keyboard input or the distance between points input. Once it has the data then draw a fillet elbow with whatever input I used. It should be simple but it’s beyond me. Here is the lisp.

I know it's a little worse than rough but it's a work in progress. 

(defun C:FE1A (/ lentha lenthb os)


(prompt "\nSET DISTANCE ")
(setq os (getvar "osmode"))
   (command "undo" "begin")

; Chooses points on two lines to measure distance.   

   (setvar "osmode" 512)
(setq lentha (getpoint "\nCHOOSE FIRST LINE: "))
(if lentha
(progn
(setvar "osmode" 128)
(setq lenthb (getpoint lentha "\nCHOOSE SECOND LINE: "))))
(if lenthb
(progn
(setq mf_radius_size1 (rtos (distance lentha lenthb)))

; sets the value to a real number autocad can use

(setq mf_radius_size (distof mf_radius_size1 4))

)
)


(setq store_temp mf_radius_size)
(prompt  "\nEnter a number <")(if (/= nil) (progn(prin1 mf_radius_size)))(prompt  ">:")
   (setq mf_radius_size (getreal))
(if (= mf_radius_size nil)(setq mf_radius_size store_temp))
   (setq b (/ mf_radius_size 1))

; Creates the duct corner 
   
       (command "fillet" "R" b "fillet" (entsel "\nPick first inner line for elbow: ") (entsel "\nPick second inner line for elbow: "))
   (setq j (+ mf_radius_size b))
    
       (command "fillet" "R" j "fillet" (entsel "\nPick first outer line for elbow: ") (entsel "\nPick second outer line for elbow: "))
  (setq the_arc (entget (entlast)))
(if (/= (cdr (assoc 0 the_arc)) "arc")
  (progn
    (setq os_setting (getvar "osmode"))
    (setvar "osmode" 0)
  (setq center_of_arc (cdr (assoc 10 the_arc)))
  (setq start_angle (cdr (assoc 50 the_arc)))
  (setq end_angle (cdr (assoc 51 the_arc)))
  (setq line_1_start (polar center_of_arc start_angle mf_radius_size))
  (setq line_1_end (polar center_of_arc start_angle (* mf_radius_size 2)))
  (command "line" line_1_start line_1_end "")
  (setq line_1_start (polar center_of_arc end_angle mf_radius_size))
  (setq line_1_end (polar center_of_arc end_angle (* mf_radius_size 2)))
  (command "line" line_1_start line_1_end "")
    (setvar "osmode" os_setting)
))
  (command "undo" "end")
(princ))

Here is something I think I can use. 

(DEFUN PRLINF()
     
     (IF
	  (= INIT NIL)
	  (WHILE
	   (= INIT NIL)
	   (SETQ INIT
     (GETDIST "\nPlease Enter Distance Between Lines: ")
	  )
     )
     (SETQ INIT
       (GETDIST
	  (STRCAT "\nPlease Enter Distance Between Lines<"
	  (RTOS DIST)
	  ">: "
     )
  )
)
);END OF IF FUNCTION
(IF
     (= INIT NIL)
     (SETQ INIT DIST)
     (SETQ DIST INIT)
     )
  ); END OF PRLINF FUNCTION
(DEFUN PRLDRW ()
     (SETQ SP (GETPOINT "\nEnter Start Point: ")
	   EP (GETPOINT SP "\nEnter End Point: ")
     SPX SP
);END SETQ
(setvar "polarmode" 0)
  (setvar "osmode" 0)
  (setvar "polarmode" 0)
(COMMAND "LINE" (SETQ osp1
	  (POLAR SP
	       (+ (ANGLE SP EP) (DTR 90))
	       (/ DIST 2)
	  )
     )
     (SETQ oep1
	  (POLAR EP
	       (+ (ANGLE SP EP) (DTR 90))
	       (/ DIST 2)
	  )
     )
     ""
     "LINE" (SETQ osp2
	  (POLAR SP
	       (- (ANGLE SP EP) (DTR 90))
	       (/ DIST 2)
	  )
     )
     (SETQ oep2
	  (POLAR EP
	       (- (ANGLE SP EP) (DTR 90))
	       (/ DIST 2)
	  )
     )
     ""
);END COMMAND
(SETQ isp1 osp1
     iep1 oep1
     isp2 osp2
     iep2 oep2
)
  (setvar "orthomode" get_ortho)
  (setvar "osmode" holding_setting_for_osmode)
  (setvar "snapmode" get_snap_setting)
   (setvar "polarmode" get_polar_setting)  
);END OF PLDRW FUNCTION

 

 

7 REPLIES 7
Message 2 of 8
Kent1Cooper
in reply to: LDShaw


@LDShaw wrote:

.... What I want it to do is decide whether it needs the keyboard input or the distance between points input. ….


 

Maybe I'm not understanding correctly, but the (getdist ) function [instead of your one instance of (getreal )] will accept either kind of input, so you don't need to choose between them.  And it will take typed input in whatever kind of units you have going, and return it as a real number -- i.e. if you're in Imperial units, you can type in 3'4-1/2" and it will return 40.5.

Kent Cooper, AIA
Message 3 of 8
doaiena
in reply to: LDShaw

If i understood you correct, you want to have the choice to either enter the distance by hand, or pick points on the screen. If so, this will get you started.

(defun c:test (/ kwrd dist p1 p2)

(prompt "\nSet the distance by entering a value or pick points. ")

(initget 1 "Value Points")
(setq kwrd (getkword "\nSet distance: [enter Value/pick Points] "))

(cond
((equal kwrd "Value") (while (not dist) (setq dist (getreal "\nEnter distance: "))))

((equal kwrd "Points")
(while (not p1) (setq p1 (getpoint "\nPick first point: ")))
(while (not p2) (setq p2 (getpoint "\nPick second point: ")))
(setq dist (distance p1 p2))
)

(T (prompt "\nNo distance was set."))
);cond


(if (> dist 0)
(progn
;insert the rest of your function here
))

(princ)
);defun
Message 4 of 8
Kent1Cooper
in reply to: doaiena


@doaiena wrote:

... you want to have the choice to either enter the distance by hand, or pick points on the screen. If so, this will get you started.

…. (getkword "\nSet distance: [enter Value/pick Points] ")) ….

 

But, see, that's exactly what you don't  need to do.  You already have the choice  to give it input either way, without  telling it which way you're going to use, if you do it with the (getdist ) function, which accepts either kind of input.

Kent Cooper, AIA
Message 5 of 8
doaiena
in reply to: Kent1Cooper

Almost all of my user inputs are done via dialogs, so i've never paid attention to the "getdist" function. Note taken!

 

I guess this boils down the initial part of the code to just a few lines

(defun c:test (/ dist)

(while (not dist) (setq dist (getdist "Enter distance or pick points")))
(if (> dist 0)
(progn
;insert the rest of your function here
))

(princ)
);defun
Message 6 of 8
dbroad
in reply to: doaiena

In addition to @Kent1Cooper 's excellent advice, remember that all of the getxxxx functions accept keywords if set up in initget immediately prior to the getxxxx function call, so there are only a few situations where you actually need getkword.

Architect, Registered NC, VA, SC, & GA.
Message 7 of 8
LDShaw
in reply to: dbroad

I still can't figure out how to get this done. I am hoping a reset on what I would like to see will help.

What I want it to do is if a distance has been used before give it as a suggestion. If it the distance is not what I need I want to either type in a number or pick two parallel lines to set the distance. 


This is my routine as it is now.

(defun c:filletelbow ()
(command "undo" "begin")
(setq store_temp mf_radius_size)
(prompt "\nEnter a number <")(if (/= nil) (progn(prin1 mf_radius_size)))(prompt ">:") (setq mf_radius_size (getdist)) (if (= mf_radius_size nil)(setq mf_radius_size store_temp)) (setq b (/ mf_radius_size 1)) ; Creates the duct (command "fillet" "R" b "fillet" (entsel "\nPick first inner line for elbow: ") (entsel "\nPick second inner line for elbow: ")) (setq j (+ mf_radius_size b)) (command "fillet" "R" j "fillet" (entsel "\nPick first outer line for elbow: ") (entsel "\nPick second outer line for elbow: ")) (setq the_arc (entget (entlast))) (if (/= (cdr (assoc 0 the_arc)) "arc") (progn (setvar "osmode" 0) (setq center_of_arc (cdr (assoc 10 the_arc))) (setq start_angle (cdr (assoc 50 the_arc))) (setq end_angle (cdr (assoc 51 the_arc))) (setq line_1_start (polar center_of_arc start_angle mf_radius_size)) (setq line_1_end (polar center_of_arc start_angle (* mf_radius_size 2))) (command "line" line_1_start line_1_end "") (setq line_1_start (polar center_of_arc end_angle mf_radius_size)) (setq line_1_end (polar center_of_arc end_angle (* mf_radius_size 2))) (command "line" line_1_start line_1_end "") (setvar "osmode" os_setting) )) (command "undo" "end") (princ))



This seems to do what I need if I can figure out how to use it. I've tried a few ways to add it but nothing seems to work out.  I've tried various forms of all the suggestions and still no luck.

(setvar "osmode" 512)
(setq lentha (getpoint "\nCHOOSE FIRST LINE: "))
(if lentha
(progn
(setvar "osmode" 128)
(setq lenthb (getpoint lentha "\nCHOOSE SECOND LINE: "))))
(if lenthb
(progn
(setq mf_radius_size1 (rtos (distance lentha lenthb)))

; sets the value to a real number autocad can use

(setq mf_radius_size (distof mf_radius_size1 4))

)
)

Any help at all is appreciated. Thank you.

 

 

Message 8 of 8
Kent1Cooper
in reply to: LDShaw


@LDShaw wrote:

.... If it the distance is not what I need I want to either type in a number or pick two parallel lines to set the distance. ....


 

For that part, that's the beauty of the (getdist) function.  You can either type in a number or just pick your two parallel lines, using NEArest [or in many cases ENDpoint or MIDpoint] Osnap on the first, and PERpendicular on the second.  Those Osnap modes can be running ones, or you can type them in or pick them from the Shift+righr-click or Ctrl+right-click list.  Code can be simply:

(setq YourRadius (getdist))

For the pick-twice option [this won't allow the typing-it-in option], f you want those modes built in so you don't have to specify them, here's an approach:

(command "_.dist" "_nea" pause "_per" pause)
(setq YourRadius (getvar 'distance))

The DIST command there will supply its own Select first point and second point prompts as well as calling for the Osnap modes.

Kent Cooper, AIA

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

Post to forums  

Forma Design Contest


AutoCAD Beta