broncos15 Posted December 4, 2015 Posted December 4, 2015 I had a quick question on why my lisp routine wouldn't be working. I am getting the error "error. bad function. 0.5" when I run the following code: (defun CheckorGetSurface () (while (not (and (setq SurfaceDefaultAdd (car (entsel "\rSelect the Main Surace you to be the default: "))) (= "AECC_TIN_SURFACE" (cdr (assoc 0 (entget SurfaceDefaultAdd)))) ) ) ) ) (defun c:makecurb (/ ss) (if (not SurfaceDefaultAdd) (CheckorGetSurface) ) (setq ss (ssget "_+.:E:S" '((0 . "AECC_FEATURE_LINE")))) (if ss (progn (command "._OffsetFeature" ("0.5" ss pause "0.5" "")) (command "AddSurfaceBreaklines" SurfaceDefaultAdd ss "") ) ) ) What's weird is that it should be a super easy routine and I can't figure out why my 0.5 distance isn't working. Quote
Lee Mac Posted December 4, 2015 Posted December 4, 2015 After a quick glance, change: (command "._OffsetFeature" ("0.5" ss pause "0.5" "")) to: (command "._OffsetFeature" "0.5" ss pause "0.5" "") Quote
broncos15 Posted December 4, 2015 Author Posted December 4, 2015 After a quick glance, change: (command "._OffsetFeature" ("0.5" ss pause "0.5" "")) to: (command "._OffsetFeature" "0.5" ss pause "0.5" "") Thanks Lee, I knew it was a stupid mistake. I have spent to much time writing in visual lisp lately and now I am making stupid mistakes in AutoLISP haha. Quote
broncos15 Posted December 4, 2015 Author Posted December 4, 2015 So when I was messing with this more I decided that I wanted to allow the user to be able to change the distance that it offsets and raises the curb. I was curious on how to make an ssget function that instead of just saying "Select object" it would instead do "Select object or [settings] " similar to how the command line version works for a lot of different commands. Quote
broncos15 Posted December 4, 2015 Author Posted December 4, 2015 So I decided to go with the entsel function even though it makes for a little more complex if statements. My issue is that when I type in settings I get "error: bad argument type: consp "Settings" and if I select a feature line it says that nothing is selected. I am wondering if it has to do with my use of getreal with the settings, but I have no idea why it isn't recognizing when I select a feature line. (defun CheckorGetSurface () (while (not (and (setq SurfaceDefaultAdd (car (entsel "\rSelect the Main Surace you to be the default: " ) ) ) (= "AECC_TIN_SURFACE" (cdr (assoc 0 (entget SurfaceDefaultAdd))) ) ) ) ) ) (defun c:makeparkingcurb (/ ss ss1 *error*) (defun *error* (msg) (if (not (member msg '("Function cancelled" "quit / exit abort")) ) (princ (strcat "\nError: " msg)) ) (princ) ) (if (not SurfaceDefaultAdd) (CheckorGetSurface) ) (initget 1 "Settings") (setq ss (car (entsel "\n Select the feature line you want to offset [settings]: " ) ) ) (if ss (if (= ss "Settings") (progn (setq offsetdist (cond ( (getreal "\nOffset Distance <0.5>: ") ) ( "0.5" ))) (setq offsetheight (cond ( (getreal "\nOffset Distance <0.5>: ") ) ( "0.5" ))) ) ) (progn (setq entlist (entget ss)) (if (= "AECC_FEATURE_LINE" (cdr (assoc 0 entlist))) (progn (command "._OffsetFeature" offsetdist ss) (princ "\nSpecify side to offset: ") (command pause offsetheight "") (setq ss1 (entlast)) (command "._AddSurfaceBreaklines" SurfaceDefaultAdd ss1 "") ) ) (princ "\nNot a feature line") ) ) (princ "\nNothing selected") (princ) ) Quote
Hippe013 Posted December 4, 2015 Posted December 4, 2015 Couple of things are a little weird with your code. If I could make a couple of suggestions. 1. If you are working with entity name maybe your setq ss should be setq ent. This allows people reading your code to quickly identify that you are working with entity names and not selection sets. 2. Offsetdist and offsetheight are not set by default. If I run this code for the first time and don't run through the settings then offsetdist is nil. 3. You should loop the original prompt so that if you go through the settings it brings you back to the original prompt. 4. Again ss1 should be maybe ent1. Otherwise it looks as if ss1 should be a selection Set when its not. Quote
Hippe013 Posted December 4, 2015 Posted December 4, 2015 I like to use getcfg and setcfg to store and retrieve my programs defaults. I would also create a subroutine that handles the settings and one to handle the selection. This way you can call the selection from the end of the settings to provide that loop back that I was describing. Quote
BIGAL Posted December 4, 2015 Posted December 4, 2015 One of the ugly things in Civ3D is turning surfaces on off select etc so I wrote a toolbar interface and a dialouge selection saves going to toolspace, so in your code above a dialouge would appear to allow the setting of default surface the nice thing though is if you have only 1 surface it will set it as defualt without the need to pick. If you look at the image you can see the contours as toolbar items including the Triangles the black sq is off. Your welcome to use the code. There is a Readme in the zip. Chcontourstoolbar.zip Quote
Lee Mac Posted December 5, 2015 Posted December 5, 2015 My issue is that when I type in settings I get "error: bad argument type: consp "Settings" and if I select a feature line it says that nothing is selected. (entsel) returns a string when a keyword is selected; (car (entsel)) will error in this case as (car) only operates on lists. Quote
broncos15 Posted December 7, 2015 Author Posted December 7, 2015 Hippe013, thank you so much for the suggestions. I tried to incorporate them into the code (I had forgot to add in to check if the variables had been created or not, so thank you!). BigAL, that toolbar is awesome! Lee, thank you for the information about entsel and car. However, I have been messing with the code and now I am getting the error "; error: bad COND syntax: (ENT (( ... ) ( ... ) ( ... )) (( ... ) ( ... )) (( ... ) ( ... ) ( ... )))" and the code will not load. I am still pretty new to LISP so I don't know how to debug a code when it won't even load. My new code is as follows: (defun CheckorGetSurface () (while (not (and (setq SurfaceDefaultAdd (car (entsel "\rSelect the Main Surace you to be the default: " ) ) ) (= "AECC_TIN_SURFACE" (cdr (assoc 0 (entget SurfaceDefaultAdd))) ) ) ) ) ) (defun c:makeparkingcurb (/ ent ent1 *error*) (defun *error* (msg) (if (not (member msg '("Function cancelled" "quit / exit abort")) ) (princ (strcat "\nError: " msg)) ) (princ) ) (if (not SurfaceDefaultAdd) (CheckorGetSurface) ) (if (not *offsetdistans*) (setq *offsetdistans* 0.5) ) (if (not *offsetheightans*) (setq *offsetheightans* 0.5) ) (setq whilestop t) (while whilestop (initget 1 "Settings eXit") (setq ent (entsel "\n Select the feature line you want to offset [settings eXit]: " ) ) (cond ent ((= ent "Settings") (setq *offsetdistans* (cond ((getreal "\nOffset Distance" "" (*offsetdistans*) ":") ) (*offsetdistans*) ) ) (setq *offsetheightans* (cond ((getreal "\nOffset Distance" "" (*offsetheightans*) ":") ) (*offsetheightans*) ) ) ) ((= ent "Settings") (setq whilestop nil)) ((setq entlist (entget ent)) (cond (= "AECC_FEATURE_LINE" (cdr (assoc 0 entlist))) (command "._OffsetFeature" *offsetdistans* ent) (princ "\nSpecify side to offset: ") (command pause *offsetheightans* "") (setq ent1 (entlast)) (command "._AddSurfaceBreaklines" SurfaceDefaultAdd ent1 "") ) (princ "\nNot a feature line") ) ) ) (princ "\nNothing selected") (princ) ) Quote
Hippe013 Posted December 7, 2015 Posted December 7, 2015 (edited) The syntax of your cond statement is incorrect. You can think of condition statement as similar to the if statement but has a bunch of slots that code can run through. If this is true do this, or if this is true do this, if niether of those are true do this and so on. cond syntax is (cond ((test expression)(do this)) ((test expression)(do this)) ((test expression)(do this)) ( T (do this)) );end cond If the first expression is true then the first 'do this' in run and the code moves on from the cond statement. If the first test expression if nil it moves to the second test expression. If that is also nil it moves on and on until (in my example) the final test expression is set to true so if all other expressions are nil the last expression will run because it is set to true. Does this help? Edited December 7, 2015 by Hippe013 typo Quote
broncos15 Posted December 7, 2015 Author Posted December 7, 2015 The syntax of your cond statement is incorrect. You can think of condition statement as similar to the if statement but has a bunch of slots that code can run through. If this is true do this, or if this is true do this, if niether of those are true do this and so on. cond syntax is (cond ((test expression)(do this)) ((test expression)(do this)) ((test expression)(do this)) ( T (do this)) );end cond If the first expression is true then the first 'do this' in run and the code moves on from the cond statement. If the first test expression if nil it moves to the second test expression. If that is also nil it moves on and on until (in my example) the final test expression is set to true so if all other expressions are nil the last expression will run because it is set to true. Does this help? Hippe013, yes that was very helpful. I was formatting the intro part of my conditional statement like how I would for an if statement, so thank you! I can get it to load now, so it will be easier to debug. Thanks again for the help. Quote
Hippe013 Posted December 7, 2015 Posted December 7, 2015 Broncos15, I can see that you are the type that wants to learn and you do most of the work yourself. You are a prime example of the type of people that I like to help. I don't wish to be on here writing request codes for people. I want to teach and guide people in their learning of LISP & VLISP. You are most welcome! regards, hippe013 Quote
broncos15 Posted December 7, 2015 Author Posted December 7, 2015 Hippe013, thank you, I really appreciate it! I am super interested in learning and getting better at lisp, so your help has been greatly appreciated. I have another quick question on my code. Why would my setting the variables *offsetdistans* and *offsetheightans* to 0.5 yield a bad function error 0.5 when I call them later in the settings? It doesn't seem to make sense because I am just setting them equal to a value and then I am I using a getreal function in the settings. Quote
Hippe013 Posted December 7, 2015 Posted December 7, 2015 (edited) *offsetdistans* is not a subroutine, its a symbol with a real value. Change: (getreal "\nOffset Distance" "" (*offsetdistans*) ":") To: (getreal (strcat "\nOffset Distance: " (rtos *offsetdistans* 2 2) ":")) strcat is going to combine a bunch of strings together. rtos converts a real number to a string. The first symbol encased in () needs to be a function, subroutine, operator or an implied list ie. '( 1 2 3 4 5) Notice the quote prior to the implied list. Edited December 7, 2015 by Hippe013 added to comment Quote
broncos15 Posted December 7, 2015 Author Posted December 7, 2015 *offsetdistans* is not a subroutine, its a symbol with a real value. Change: (getreal "\nOffset Distance" "" (*offsetdistans*) ":") To: (getreal (strcat "\nOffset Distance: " (rtos *offsetdistans* 2 2) ":")) strcat is going to combine a bunch of strings together. rtos converts a real number to a string. The first symbol encased in () needs to be a function, subroutine, operator or an implied list ie. '( 1 2 3 4 5) Notice the quote prior to the implied list. Hippe013, thank you. If I understand, the 2 2 for the rtos converts it to a decimal with 2 decimal places, correct? Also, why would I get "Error: bad argument type: numberp: "\nOffset Distance: 0.50:" after incorporating your code? Quote
Hippe013 Posted December 7, 2015 Posted December 7, 2015 Repost your code up to date. I will run a quick debug on it. I like to animate my code in vlide. It runs through the code step by step and typical stops on the spot causing the error. Quote
broncos15 Posted December 7, 2015 Author Posted December 7, 2015 Hippe013, thank you again for your help. I really do appreciate it. (defun CheckorGetSurface () (while (not (and (setq SurfaceDefaultAdd (car (entsel "\rSelect the Main Surace you to be the default: " ) ) ) (= "AECC_TIN_SURFACE" (cdr (assoc 0 (entget SurfaceDefaultAdd))) ) ) ) ) ) (defun c:makeparkingcurb (/ ent ent1 *error*) (defun *error* (msg) (if (not (member msg '("Function cancelled" "quit / exit abort")) ) (princ (strcat "\nError: " msg)) ) (princ) ) (if (not SurfaceDefaultAdd) (CheckorGetSurface) ) (if (not *offsetdistans*) (setq *offsetdistans* 0.5) ) (if (not *offsetheightans*) (setq *offsetheightans* 0.5) ) (setq whilestop t) (while whilestop (initget 1 "Settings eXit") (setq ent (entsel "\n Select the feature line you want to offset [settings eXit]: " ) ) (cond ((= ent "Settings") ((setq *offsetdistans* (cond (getreal (strcat "\nOffset Distance: " (rtos *offsetdistans* 2 2) ":")) (rtos *offsetheightans* 2 2) ) ) (setq *offsetheightans* (cond (getreal (strcat "\nOffset Elevation Difference: " (rtos *offsetheightans* 2 2) ":")) (rtos *offsetheightans* 2 2) ) )) ) ((= ent "eXit") (setq whilestop nil) ) ((setq entlist (entget ent)) (cond (= "AECC_FEATURE_LINE" (cdr (assoc 0 entlist))) (command "._OffsetFeature" *offsetdistans* ent) (princ "\nSpecify side to offset: ") (command pause *offsetheightans* "") (setq ent1 (entlast)) (command "._AddSurfaceBreaklines" SurfaceDefaultAdd ent1 "") ) (princ "\nNot a feature line") ) ) ) (princ) ) Quote
Hippe013 Posted December 7, 2015 Posted December 7, 2015 A couple of things are awry. 1. Your cond statement is still out of whack. 2. (setq entlist (entget ent)) Doesn't work because the value of ent is not an entity name. It is a selection returned by entsel. Try changing to (setq [color="red"]sel[/color] (entsel "\n Select the feature line you want to offset [settings eXit]: ") Because at this point you are not working with an entity you are working with a selection returned by entsel. ie. ( (2415.64 7423.17 0.0)) The car of the this sel returns the enitity name. This is why I stress to use symbol names simlar to the data type that it represents. I would also again recommend using subroutines to handle your cond statements. Just makes the code easier to read. Give me a second and I'll type up an example. Quote
Hippe013 Posted December 7, 2015 Posted December 7, 2015 (defun BRONC:settings () (while (not *offsetdistans*) (setq *offsetdistans* (getreal "\nEnter Offset Distance: " )) (if (not *offsetdistans*) (princ "\nHEY YOU! I need some input here!"))) (while (not *offsetheightans*) (setq *offsetheight* (getreal "\nEnter Elevation Difference: ")) (if (not *offsetheightans*) (princ "\nHEY YOU! I need some input here!"))) ) (defun BRONC:exit () (princ "\nYou have exited my program. Good Day to you Sir!") (princ) ) (initget "Settings eXit") (setq sel (entsel "\nSelect the feature line you want to offset [settings eXit]: ")) (cond ([color="blue"](= sel "Settings" )[/color][color="lime"](BRONC:settings)[/color]);User has selected setttings ([color="blue"](= sel "eXit")[/color][color="lime"](BRONC:exit)[/color]);User has selected to exit [color="blue"]((/= sel nil)[/color][color="lime"](setq ent (car sel)) (BRONC:moveonIhaveaselection)[/color]);if its is neither settings or exit and its not nil it must be a slection returned by entsel );end cond This is an example of how I like to use the condition statement. Use Subroutines - It makes it easier to read and not get lost in the code. Quote
Recommended Posts
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.