dlanorh Posted August 31, 2018 Posted August 31, 2018 13 minutes ago, loudy000 said: 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. See also my post above. OK, if you know what the value will be in a (key . value) pair i.e. it is fixed you can create it like the following (setq key "layer" value "0" a '(key . value) b (quote (key . value)) c (list (cons key value)) );end_setq In the above setq's a = (KEY . VALUE) b = (KEY . VALUE) c = ("LAYER" . "0") The apostrophe '(key . value) means what followsthe apostrophe is literal The (quote (key . value)) is also literal The (list (cons key value)) evaluates the expression before making the list. (cons) is autolisp's list constructor Read more HERE . It's also explained better. So lists can be constructed and contain both literal and evaluated data. The proviso is that the list construction must start with (list) if any single item is evaluated. (setq spacing 200 myblock "block1" p_list (list (list '("layer" . "block1_layer") (cons "spacing" spacing) (cons "start_offset" (/ spacing 2)))) mylist (cons myblock1 p_list) );end_setq ==>> mylist = ("block1" (("layer" . "block1_layer") ("spacing" . 200) ("start_offset" . 100))) Notice in the above that the outer list is not an associative list (no dot seperates "block1" and the associative parameter list) and should be therefore be accessed as follows (setq blk_name (car mylist) paramlst (cadr mylist) ) blk_name = "block1" paramlst = (("layer" . "block1_layer") ("spacing" . 200) ("start_offset" . 100)) whilst (cdr mylist) = ((("layer" . "block1_layer") ("spacing" . 200) ("start_offset" . 100))) NOTICE EXTRA SET OF BRACKETS OR (setq blk_name (nth 0 mylist) paramlst (nth 1 mylist) ) Using cdr would be wrong in the upper of the two as the returned list is not an associative list but a list of an associative list, making it much harder to access The lower can be used because you know what the list order will be having constructed it. Associative list are great for long lists of data (entget list is an example) and you don't know the order of the list that will be returned. However if you are constructing the list, so you know the order and can simplify it. (setq blk_lst (list (list "block1" 200 "block1_layer")(list "block2" 300 "block2_layer")) mylist nil ) (foreach b_lst blk_lst (setq tmp_lst (list (nth 0 b_lst) (nth 1 b_lst) (/ (nth 1 b_lst) 2) (nth 2 b_lst)) mylist (cons tmp_lst mylist) ) ) (setq mylist (reverse mylist) mylist = (("block1" 200 100 "block1_layer") ("block2" 300 150 "block2_layer")) mylist is a list of lists. The order of items in each individual list is the same so (foreach lst mylist (setq blk_name (nth 0 lst) spacing (nth 1 lst) start_offset (nth 2 lst) blk_lyr (nth 3 lst) ) ;do rest of stuff here );end foreach Clear as mud THIS is a good place to start reading, then play around in autocad on the command line. Create lists manually and try to access them then try to construct list and access them. Quote
dlanorh Posted August 31, 2018 Posted August 31, 2018 33 minutes ago, loudy000 said: 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 Post what you have, and tell me exactly what you are trying to achieve and i'll try to help, as will others. I know you're getting data from the user (how?) then using this with c:mes to insert blocks onto lines/polylines etc but a detailed explanation or program flow would help. Remember, Oak trees develop from acorns. Quote
loudy000 Posted September 1, 2018 Author Posted September 1, 2018 11 hours ago, loudy000 said: ; 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 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 Thank you dlanorh. The above code is fine for me the only thing that I want to add is layer property for each block. So more of like... Block1, start offset, spacing, layer that’s it. i get your explanation on functions where I’m lost is the process of putting them together. Sorry not in fmy computer can not attach what I’ve got so far. Thanks again. Quote
dlanorh Posted September 1, 2018 Posted September 1, 2018 (edited) OK, attached is an updated lisp and test drawing. You can play around with it as you see fit. Remember for every new block added to the paramlst, if it has a new layer, that layer and its settings must be added to the lyrlst. mes.lsp mes-test.dwg Edited September 1, 2018 by dlanorh 1 Quote
BIGAL Posted September 1, 2018 Posted September 1, 2018 Just me but I would not hard code the items your looking for rather use one of these two ideas. 1. Use a csv file that you read for your list items very easy to edit as its a text file Block,offset, dist, layer. You can have different variations multiple files. See lee-mac csv -> list 2. I would use a dcl list pick the blocks from the list see Lee-mac.com, same for layer then a DCL for offset and dist see getvals3. 3. yeah an extra pick the blocks on the screen just ask for layer name if same say press <enter> last DCL offset, dist. GETVALS3.lsp Quote
loudy000 Posted September 2, 2018 Author Posted September 2, 2018 6 hours ago, dlanorh said: OK, attached is an updated lisp and test drawing. You can play around with it as you see fit. Remember for every new block added to the paramlst, if it has a new layer, that layer and its settings must be added to the lyrlst. mes.lsp mes-test.dwg 6 hours ago, dlanorh said: OK, attached is an updated lisp and test drawing. You can play around with it as you see fit. Remember for every new block added to the paramlst, if it has a new layer, that layer and its settings must be added to the lyrlst. mes.lsp mes-test.dwg Brilliant! Thank you Very much. Quote
loudy000 Posted September 2, 2018 Author Posted September 2, 2018 4 hours ago, BIGAL said: Just me but I would not hard code the items your looking for rather use one of these two ideas. 1. Use a csv file that you read for your list items very easy to edit as its a text file Block,offset, dist, layer. You can have different variations multiple files. See lee-mac csv -> list 2. I would use a dcl list pick the blocks from the list see Lee-mac.com, same for layer then a DCL for offset and dist see getvals3. 3. yeah an extra pick the blocks on the screen just ask for layer name if same say press <enter> last DCL offset, dist. GETVALS3.lsp This sounds great at the same time looks complicated to me . I'd like to try it though. Thanks Bigal. 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.