loudy000 Posted August 29, 2018 Posted August 29, 2018 (edited) First of all thanks to dlanorh for providing below routine which works great. Now i have different blocks with different distances, what im thinking is if is possible to create presets without copying over and over again the whole routing and change the block names and distances? ; original code by Dlanorh July 2018 (defun c:mes (/ c_doc ms obj e_pt p_len dist i_pt i_param b_ang n_obj o_lst) (vl-load-com) (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt) dist 0 );end_setq (while (< dist p_len) (setq i_pt (vlax-curve-getpointatdist obj dist) i_param (vlax-curve-getparamatpoint obj i_pt) b_ang (angle '(0 0 0) (vlax-curve-getfirstderiv obj i_param)) n_obj (vla-insertblock ms (vlax-3d-point i_pt) "BLOCK1" 1.0 1.0 1.0 b_ang) o_lst (cons n_obj o_lst) dist (+ dist 8) );end_setq );end_while (initget "Yes No") (if (= (getkword "Flip Block? [Yes / No] : ") "Yes") (foreach n_obj o_lst (vlax-put-property n_obj 'rotation (+ (vlax-get-property n_obj 'rotation) pi)) );end_foreach );end_if );end_defun ;;;;;;CREATE PRESETS (defun c:BLOCK1 ( / ) (while (mes BLOCKNAME STARTDIST OFFSET) ) ) maybe something like what Emmanuel did here (Presets) ;;;;;;CREATE PRESETS (defun c:BLOCK1 ( / ) (while (mes BLOCKNAME1 STARTDIST1 OFFSET1) ) ) (defun c:BLOCK2 ( / ) (while (mes BLOCKNAME2 STARTDIST2 OFFSET2) ) ) (defun c:BLOCK3 ( / ) (while (mes BLOCKNAME3 STARTDIST3 OFFSET3) ) ) Many Thanks Edited August 29, 2018 by loudy000 Quote
Jef! Posted August 30, 2018 Posted August 30, 2018 (edited) Hi loody. This seems the perfect candidate for the assoc function. Just build a list made of block name/dist associated lists. That way you can dynamically retrieve the dist from the assoc using the block name as the key. Not duplicating routines is the best way to avoid discrepancies if you need to make modifications... (progn (setq paramlst '(("block1" . 3)("block2" . 5)("block3" . 8))) (setq bname "block1") (setq dist (cdr (assoc bname paramlst))) ) Cheers Edited August 30, 2018 by Jef! removed HTML highlighting 1 Quote
loudy000 Posted August 30, 2018 Author Posted August 30, 2018 46 minutes ago, Jef! said: Hi loody. This seems the perfect candidate for the assoc function. Just build a list made of block name/dist associated lists. That way you can dynamically retrieve the dist from the assoc using the block name as the key. Not duplicating routines is the best way to avoid discrepancies if you need to make modifications... (progn (setq paramlst '(("block1" . 3)("block2" . 5)("block3" . 8))) (setq bname "block1") (setq dist (cdr (assoc bname paramlst))) ) Cheers Hi Jef Thanks again for helping me, sorry but where do i put that in above code? do i just add that? Quote
Jef! Posted August 30, 2018 Posted August 30, 2018 (edited) 2 hours ago, loudy000 said: Hi Jef Thanks again for helping me, sorry but where do i put that in above code? do i just add that? Not quite, this was a "standalone" demo of the concept. I'm not sure I understand exactly what you want to do... you want to replace the increment addition of 8 that is in the while, and choose the block at the beginning, right? You will need to add the paramlst on the first setq call (with cdoc, ms...) along with the user's choice. Don't forget that setq can set any amount of variables at once....: (progn (setq paramlst '(("block1" . 3)("block2" . 5)("block3" . 8))) (setq bname "block1") (setq dist (cdr (assoc bname paramlst))) ) ;is the same as (setq paramlst '(("block1" . 3)("block2" . 5)("block3" . 8)) bname "block1" dist (cdr (assoc bname paramlst)) ) Basically at the beginning the variables are setq'ed on a single setq call, which mean that if you want to add the paramlst variable inside, you have to exclude the setq, like that: (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt) dist 0 paramlst '(("block1" . 3)("block2" . 5)("block3" . 8)) );end_setq Now for the user choice, we need to put it in a variable, but since we need to use initget first, we will do it just after the original setq. For the initget we will use 1 as the first argument to prevent the user to return "" if he hits enter. For the 2nd argument we need to give it a string made of all the choices separated by a space (like this "block1 block2 block3"). After that we will use getkword, which need as an argument a string containing all choices separated by /, all of it enclosed in square brackets (like this "[block1/block2/block3]"). Since this is driven by the list of choices in the paramlst variable, and we wont want to need to update both initget and getkword strings each time we add a choice in paramlst, we will make both initget and keywork dynamic and automatic. Try to follow the logic step by step of what I did to get from paramlst to the 2 required strings. (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst))))) (i wont be using code tags to be able to bold parts and add colors to show you step by step evaluation of if. Don't bite me Hulk!) (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst))))) Paramlst contains (("block1" . 3) ("block2" . 5) ("block3" . 8)) (mapcar 'car paramlst) will return ("block1" "block2" "block3"), a list made of the car of each of the list elements. (initget 1 (vl-string-right-trim " " (apply 'strcat (mapcar '(lambda (x) (strcat x " ")) '("block1" "block2" "block3") ) ))) (mapcar '(lambda (x) (strcat x " ")) '("block1" "block2" "block3")) will return ("block1 " "block2 " "block3 "), a list made of the a concatenation of each string with a space (initget 1 (vl-string-right-trim " " (apply 'strcat '("block1 " "block2 " "block3 ") ) )) (apply 'strcat '("block1 " "block2 " "block3 ") ) will return "block1 block2 block3 ", which is the equivalent of (strcat "block1 " "block2 " "block3 ") (initget 1 (vl-string-right-trim " " "block1 block2 block3 " )) (vl-string-right-trim " " "block1 block2 block3 " ) will remove any space at the right of the string and will return "block1 block2 block3". And now we are left with (initget 1 "block1 block2 block3") For the getkword, I took the same approach but used "/" instead of a space " " in the strcat and vl-string-right-trim, but had to add the square brackets hence the extra strcat "[" string "]". Since we will use the value later, the returned value of getkword could be stored in a variable. (setq bname (getkword (strcat "[" (vl-string-right-trim "/"(apply 'strcat (mapcar '(lambda (x) (strcat x "/")) (mapcar 'car paramlst)))) "]" ) )) Now the only part left to be done is to use the block name from the getkword stored in bname variable rather than the name "block1" currently used in the vla-insert-block, and localize the new variables, paramlst and bname. Try to do it first than compare with this... ; original code by Dlanorh July 2018 ;with some modifs by Jef! made on the following thread ;https://www.cadtutor.net/forum/topic/65895-creating-presets/ (defun c:mes (/ c_doc ms obj e_pt p_len dist i_pt i_param b_ang n_obj o_lst paramlst bname) (vl-load-com) (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt) paramlst '(("block1" . 3) ("block2" . 5) ("block3" . 8));Jef! dist 0 );end_setq (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst)))));Jef! (setq bname (getkword (strcat "["(vl-string-right-trim "/"(apply 'strcat (mapcar '(lambda (x) (strcat x "/")) (mapcar 'car paramlst))))"]")));Jef! (while (< dist p_len) (setq i_pt (vlax-curve-getpointatdist obj dist) i_param (vlax-curve-getparamatpoint obj i_pt) b_ang (angle '(0 0 0) (vlax-curve-getfirstderiv obj i_param)) n_obj (vla-insertblock ms (vlax-3d-point i_pt) bname 1.0 1.0 1.0 b_ang); Jef! - we insert bname instead of "block1" o_lst (cons n_obj o_lst) dist (+ dist (cdr (assoc bname paramlst)));;;now we get dist increment from paramlst using bname );end_setq );end_while (initget "Yes No") (if (= (getkword "Flip Block? [Yes / No] : ") "Yes") (foreach n_obj o_lst (vlax-put-property n_obj 'rotation (+ (vlax-get-property n_obj 'rotation) pi)) );end_foreach );end_if );end_defun Edited August 30, 2018 by Jef! removed HTML syntax highlighting from code 2 Quote
loudy000 Posted August 30, 2018 Author Posted August 30, 2018 2 minutes ago, Jef! said: paramlst '(("block1" . 3) ("block2" . 5) ("block3" . 8));Jef! dist 0 wowwww! i didnt try it yet but i need also to set "dist 0" in different distance so say it'll look like ("block1" . 3 .5); blockname, start distance, block distances not sure though if that how it will look like just an idea you're awesome! Quote
Jef! Posted August 30, 2018 Posted August 30, 2018 (edited) 20 minutes ago, loudy000 said: wowwww! i didnt try it yet but i need also to set "dist 0" in different distance so say it'll look like ("block1" . 3 .5); blockname, start distance, block distances not sure though if that how it will look like just an idea you're awesome! Thanks. Assoc lists can only contain a key and a value (key . value). The value could be a list tho. You could apply the same concept with the value, using another list assoc list. (defun c:tst ( / paramlst bname dist start) (setq paramlst '(("block1" . (("start" . 3)("dist" . 4))) ("block2" . (("start" . 5)("dist" . 6))))) (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst))))) (setq bname (getkword (strcat "["(vl-string-right-trim "/"(apply 'strcat (mapcar '(lambda (x) (strcat x "/")) (mapcar 'car paramlst))))"]"))) (setq dist (cdr (assoc "dist" (cdr (assoc bname paramlst))))) (setq start (cdr (assoc "start" (cdr (assoc bname paramlst))))) (alert (strcat "block chosen: " bname "\nStart value: "(vl-princ-to-string start) "\nDist value: "(vl-princ-to-string dist))) ) Now instead of having a numeric value, if the user select the "block1", (assoc "block1" paramlst) will return (("start" . 3)("dist" . 4))). In that list we can then get both the assoc "start" or "dist". Nice hmm? Edited August 30, 2018 by Jef! highlighting... again. Quote
loudy000 Posted August 30, 2018 Author Posted August 30, 2018 (edited) 1 hour ago, Jef! said: Thanks. Assoc lists can only contain a key and a value (key . value). The value could be a list tho. You could apply the same concept with the value, using another list assoc list. (defun c:tst ( / paramlst bname dist start) (setq paramlst '(("block1" . (("start" . 3)("dist" . 4))) ("block2" . (("start" . 5)("dist" . 6))))) (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst))))) (setq bname (getkword (strcat "["(vl-string-right-trim "/"(apply 'strcat (mapcar '(lambda (x) (strcat x "/")) (mapcar 'car paramlst))))"]"))) (setq dist (cdr (assoc "dist" (cdr (assoc bname paramlst))))) (setq start (cdr (assoc "start" (cdr (assoc bname paramlst))))) (alert (strcat "block chosen: " bname "\nStart value: "(vl-princ-to-string start) "\nDist value: "(vl-princ-to-string dist))) ) Now instead of having a numeric value, if the user select the "block1", (assoc "block1" paramlst) will return (("start" . 3)("dist" . 4))). In that list we can then get both the assoc "start" or "dist". Nice hmm? ok so im totally lost and cant follow so is that standalone command that needs to go first? sorry really confused the only lisp that i can do is something like this (Defun c:mn () (command "matchprop")) HAHA not even sure if that's a lisp lol, anyways i tried it and i got error saying bad argument. again thanks for helping really appreciate it p.s (("start" . 3)("dist" . 4)(block1 layer)) ? If possible many many thanks Edited August 30, 2018 by loudy000 Quote
Jef! Posted August 31, 2018 Posted August 31, 2018 2 minutes ago, loudy000 said: is that standalone command that needs to go first? This was a "standalone" demo of the concept of associated lists (start dist) stored as values inside a another assoc list. Do you understand the concept of associated lists? It is a list made of (KEYs . VALUEs) like that: ((KEY1 . VALUE)(KEY1 . VALUE)) if you have a lst define as such: (setq LST ' (("a" . 1) ("b" . 2)) ) (assoc "a" LST) would return the (KEY . VALUE) assoc that has "a" as its KEY, so in this example ("a" . 1). (assoc "b" LST) would return the (KEY . VALUE) assoc that has "b" as its KEY, so in this example ("b" . 2). In a list, the car function returns the 1rst element. The cdr function will return a list without the 1rst element (so everything after the car). On a dotted pair (also referred as assoc), it returns the 2nd element, the VALUE To retrieve only VALUE stored in the "a" assoc of the list LST, you would use (cdr (assoc "a" LST) ). ... if you have been following so far, you understood that (assoc "a" LST) will return ("a" . 1). Evaluated, (cdr (assoc "a" LST) ) becomes (cdr ("a" . 1)) which will return the VALUE associated to the "a" KEY of the LST list. To go back to my (first) stand alone demo, I had this (setq PARAMLST ' (("block1" . 3) ("block2" . 5)) ) In my last demo, instead of having let's say just a "simple" 3 as a VALUE stored for "block1", I store a list (("start" . 3)("dist" . 4)) In my last demo, instead of having let's say just a "simple" 5 as a VALUE stored for "block2", I store a list (("start" . 5)("dist" . 6)) (setq PARAMLST ' (("block1" . (("start" . 3)("dist" . 4))) ("block2" . (("start" . 5)("dist" . 6)))) ) (so far so good?) Now, If the user chose "block1", we have to search for the corresponding assoc (assoc "block1" PARAMLST) would return: ("block1" . (("start" . 3)("dist" . 4))) ... but we only need the VALUE (cdr (assoc "block1" PARAMLST)) would return only the value: (("start" . 3)("dist" . 4)) Now, lets look closely at the VALUE (("start" . 3)("dist" . 4)) now, just for fun, let's change the color of it to see if you recognize the same pattern (("start" . 3)("dist" . 4)) ... it is the same format as my LST example from the beginning of this reply. 1 hour ago, loudy000 said: ok so im totally lost and cant follow Don't be afraid to google things out. I'm *probably* not the first one to explain car, cdr and assoc, and that knowledge can be very easily found. Just focus on examples, and homework: spend at least the same amount of time trying to understand and figuring out examples provided "on your own" as the time you think it took me to make a reply such as the ones I gave you. (ie.: don't post "I don't understand" 8 minutes after I posted something that took me an hour to write). Focus, and give it a genuine try, I guarantee that you will be amazed at the amount of things you can understand and deduct. Be careful tho, LISP is highly addictive! Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 Thanks I’ll do that and come back again Thanks for detailed explanation:) Yeah I know it’s addictive:D I’ll try again tomorrow many thanks Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 (edited) ; original code by Dlanorh July 2018 ;with some modifs by Jef! made on the following thread ;https://www.cadtutor.net/forum/topic/65895-creating-presets/ (defun c:mes (/ c_doc ms obj e_pt p_len start dist i_pt i_param b_ang n_obj o_lst paramlst bname) (vl-load-com) (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt)) (setq paramlst ' (("block1" . (("start" . 0)("dist" . 4))) ("block2" . (("start" . 2)("dist" . 8)))) );end_setq (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst)))));Jef! (setq bname (getkword (strcat "["(vl-string-right-trim "/"(apply 'strcat (mapcar '(lambda (x) (strcat x "/")) (mapcar 'car paramlst))))"]")));Jef! (setq dist (cdr (assoc "dist" (cdr (assoc bname paramlst))))) (setq start (cdr (assoc "start" (cdr (assoc bname paramlst))))) ;(alert (strcat "block chosen: " bname "\nStart value: "(vl-princ-to-string start) "\nDist value: "(vl-princ-to-string dist))) (while (< dist p_len) (setq i_pt (vlax-curve-getpointatdist obj dist) i_param (vlax-curve-getparamatpoint obj i_pt) b_ang (angle '(0 0 0) (vlax-curve-getfirstderiv obj i_param)) n_obj (vla-insertblock ms (vlax-3d-point i_pt) bname 1.0 1.0 1.0 b_ang); Jef! - we insert bname instead of "block1" o_lst (cons n_obj o_lst) dist (+ dist (cdr (assoc bname paramlst)));;;now we get dist increment from paramlst using bname );end_setq );end_while (initget "Yes No") (if (= (getkword "Flip Block? [Yes / No] : ") "Yes") (foreach n_obj o_lst (vlax-put-property n_obj 'rotation (+ (vlax-get-property n_obj 'rotation) pi)) );end_foreach );end_if );end_defun So that's what ive got so far, i tried to open it on vlide and the break is saying something to do with dist (+ dist (cdr (assoc bname paramlst))) and when i ran it to cad ive got Quote ; error: bad argument type: numberp: (("start" . 0) ("dist" . 4)) will try again Edited August 31, 2018 by loudy000 Quote
dlanorh Posted August 31, 2018 Posted August 31, 2018 This bit is slightly wrong. You are trying to setq within a setq. (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt)) (setq paramlst ' (("block1" . (("start" . 0)("dist" . 4))) ("block2" . (("start" . 2)("dist" . 8)))) );end_setq It should be (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt)) paramlst '(("block1" . (("start" . 0)("dist" . 4))) ("block2" . (("start" . 2)("dist" . 8)))) );end_setq Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 8 minutes ago, dlanorh said: This bit is slightly wrong. You are trying to setq within a setq. (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt)) (setq paramlst ' (("block1" . (("start" . 0)("dist" . 4))) ("block2" . (("start" . 2)("dist" . 8)))) );end_setq It should be (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt)) paramlst '(("block1" . (("start" . 0)("dist" . 4))) ("block2" . (("start" . 2)("dist" . 8)))) );end_setq yeah i tried that already but didn't work for me Quote
dlanorh Posted August 31, 2018 Posted August 31, 2018 I'm not entirely sure this is correct, but try changing dist (+ dist (cdr (assoc bname paramlst))) to dist (+ start dist) 1 Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 23 minutes ago, dlanorh said: dist (+ start dist) perfect Many Thanks @dlanorh Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 ; original code by Dlanorh July 2018 ;with some modifs by Jef! made on the following thread ;https://www.cadtutor.net/forum/topic/65895-creating-presets/ (defun c:mes (/ c_doc ms obj e_pt p_len spacing start_offset i_pt i_param b_ang n_obj o_lst paramlst bname) (vl-load-com) (setq c_doc (vla-get-activedocument (vlax-get-acad-object)) ms (vla-get-modelspace c_doc) obj (vlax-ename->vla-object (car (entsel "\nSelect arc, line, spline or polyline : "))) e_pt (vlax-curve-getendpoint obj) p_len (vlax-curve-getdistatpoint obj e_pt) paramlst '( ("block1" . (("spacing" . 200)("start_offset" . 100))) ("block2" . (("spacing" . 200)("start_offset" . 0)))) );end_setq (initget 1 (vl-string-right-trim " "(apply 'strcat (mapcar '(lambda (x) (strcat x " ")) (mapcar 'car paramlst))))) (setq bname (getkword (strcat "["(vl-string-right-trim "/"(apply 'strcat (mapcar '(lambda (x) (strcat x "/")) (mapcar 'car paramlst))))"]"))) (setq start_offset (cdr (assoc "start_offset" (cdr (assoc bname paramlst))))) (setq spacing (cdr (assoc "spacing" (cdr (assoc bname paramlst))))) ;(alert (strcat "block chosen: " bname "\nStart value: "(vl-princ-to-string spacing) "\nDist value: "(vl-princ-to-string start_offset))) (while (< start_offset p_len) (setq i_pt (vlax-curve-getpointatdist obj start_offset) i_param (vlax-curve-getparamatpoint obj i_pt) b_ang (angle '(0 0 0) (vlax-curve-getfirstderiv obj i_param)) n_obj (vla-insertblock ms (vlax-3d-point i_pt) bname 1.0 1.0 1.0 b_ang); Jef! - we insert bname instead of "block1" o_lst (cons n_obj o_lst) start_offset (+ start_offset spacing);start_offset (+ start_offset (cdr (assoc bname paramlst)));;;now we get start_offset increment from paramlst using bname );end_setq );end_while (initget "Yes No") (if (= (getkword "Flip Block? [Yes / No] : ") "Yes") (foreach n_obj o_lst (vlax-put-property n_obj 'rotation (+ (vlax-get-property n_obj 'rotation) pi)) );end_foreach );end_if );end_defun I'm back so above is the working routine if anyone is interested. Thanks to Dlanorh & Jef i just change the variable name so i wont get confuse and commented the alert i dont need them for now. I also like to develop it further so i'm trying to do something like this Quote ("block1" . (("spacing" . 200)("start_offset" . (/spacing 2))) but for some reason it's not working, basically i will have 1 block which offset is starting at 0 and another one which is spacing/2, so if the spacing is 200, start offset will return 100 and lastly to add layer for each block ("block1" . (("spacing" . 200)("start_offset" . 100)("layer" . (command "-layer" "make" "BLOCK1_LAYER" "color" "1" "" "lw" "0.5" "" "lt" "continuous" "")))) i did something like above but the routine is ignoring it and didn't create layer. Thank you again for the guidance apologies if my questions doesn't make sense Quote
dlanorh Posted August 31, 2018 Posted August 31, 2018 (edited) From what I can see "paramlst" is a quoted list (it has a " ' " before the list). This means that everything in the list is taken as written, you can't do anything in a quoted list. You will need another variable for the spacing distance and then you will need to construct your param list using "list" (setq paramlst (list (cons "block1" (list (cons "spacing" spacing_dist) (cons "start_offset" (/ spacing_dist 2)))))) etc Alternatively you cound change function (c:mes) into function (defun mes ( paramlst / ......) and construct the list outside and pass it in. This is worth considering as you can foreach the main paramlst and just send in the parameters for each block e.g. ("block1" . (("spacing" . 200)("start_offset" . 100)("layer" . "block1_layer"))) is the first block passed in, where this is all constructed outside the function This is simpler to understand, simplifies the function and is easier to debug. Edited August 31, 2018 by dlanorh Quote
Jef! Posted August 31, 2018 Posted August 31, 2018 (edited) 1 hour ago, loudy000 said: Quote ("block1" . (("spacing" . 200)("start_offset" . (/spacing 2))) but for some reason it's not working, ... If your start offset is always half the value of the spacing, just calculate it. The purpose of an assoc list is to store (all and only) what cannot be calculated in an equation, like the varying arbitrary values of spacing therefore you store it in the list. Once you retrieved it (after the selection by the user), if the offset is always half the spacing value, then just calculate it, ie (setq start_offset (/ spacing 2.0)). <- note that... a) you need a space between a function and its first argument. b) if you divide an integer by an integer the result will always be an integer. 13 / 2 returns 6 - which is the whole part only. To force a result to be a float at least one of the parameters have to be a float, ie dividing by 2.0 1 hour ago, loudy000 said: i did something like above but the routine is ignoring it and didn't create layer. Why are you trying to shove that in the assoc list? An assoc list is (KEY . VALUE). A value can be an integer, a float, a string or a list. NOT function or command. The layer has to be created anyway no matter what block the user chose, it doesn't belong in the list. The layer name is different, but yet always the same: a concatenation of the value of bname and "_layer". Just make it on the fly! Edited August 31, 2018 by Jef! Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 3 hours ago, dlanorh said: e.g. ("block1" . (("spacing" . 200)("start_offset" . 100)("layer" . "block1_layer"))) Hi dlanorh this looks a bit easier to debug can you show an example how to do this, sorry guys for the last ng thread it’s just I’m not really coder, but I’m trying . Thank you very much. Quote
dlanorh Posted August 31, 2018 Posted August 31, 2018 (edited) For your information, this doesn't create what you think it does. ("layer" . (command "-layer" "make" "BLOCK1_LAYER" "color" "1" "" "lw" "0.5" "" "lt" "continuous" "")) If you cut and paste the following into the command line then press return, it will create the layer and set it as current (note that there is an extra return ("") added at the end to close the command). (command "-layer" "make" "BLOCK1_LAYER" "color" "1" "" "lw" "0.5" "" "lt" "continuous" "" "") The next line will read "command: nil" It does not return the name of the layer created so what you have in fact created is ("layer" . nil) This is true of almost all (command ....) calls in lisp. It is far better to pass in the layer name, extract it then test if it exists, and if not create it. (setq mylayer (cdr (assoc "layer" mylist))) (if (not (tblsearch "layer" mylayer));if it doesn't exist (command "_-layer" "_M" mylayer "_C" "1" "_LT" "continous" .....);make it and set current (setvar "clayer" mylayer);does exist, make it current );end_if Edited August 31, 2018 by dlanorh 1 Quote
loudy000 Posted August 31, 2018 Author Posted August 31, 2018 1 hour ago, dlanorh said: For your information, this doesn't create what you think it does. ("layer" . (command "-layer" "make" "BLOCK1_LAYER" "color" "1" "" "lw" "0.5" "" "lt" "continuous" "")) If you cut and paste the following into the command line then press return, it will create the layer and set it as current (note that there is an extra return ("") added at the end to close the command). (command "-layer" "make" "BLOCK1_LAYER" "color" "1" "" "lw" "0.5" "" "lt" "continuous" "" "") The next line will read "command: nil" It does not return the name of the layer created so what you have in fact created is ("layer" . nil) This is true of almost all (command ....) calls in lisp. It is far better to pass in the layer name, extract it then test if it exists, and if not create it. (setq mylayer (cdr (assoc "layer" mylist))) (if (not (tblsearch "layer" mylayer));if it doesn't exist (command "_-layer" "_M" mylayer "_C" "1" "_LT" "continous" .....);make it and set current (setvar "clayer" mylayer);does exist, make it current );end_if ah i don't know how to proceed anymore at least for now i'll just change layers manually Thanks for your help really appreciate 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.