Jump to content

Creating Presets


loudy000

Recommended Posts

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.

Link to comment
Share on other sites

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. :)

Link to comment
Share on other sites

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 :D 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.

Link to comment
Share on other sites

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 by dlanorh
  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :D . I'd like to try it though. :) Thanks Bigal.

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...