New to lisp

New to lisp

rfigueroa24PK4
Contributor Contributor
1,824 Views
22 Replies
Message 1 of 23

New to lisp

rfigueroa24PK4
Contributor
Contributor

Hello all

 

As the title says I'm new to lisp and I am trying to create and see how these things work. I am currently in need of a lisp routine that will do wire labels for me.

 

I have 8 different label types based on signal type. V, A, S, P, C, N, NA, NV, RF

All labels would have a Prefix and 3 digits such as "A001"

The attributes are in blocks

There are 3 different blocks "WIRE-IN",  "WIRE-OUT" and "POWER-IN"

BOTH the wire-in and wire-out have a "WIRE" Tag attribute. The power-in has a "WIRE 1" and "WIRE 2" Tag attribute.

I would like to click once on each type of block and it automatically label it the next number in sequence

example: click on one wire-in block and it label A001 and click on one wire-out block and it label A001, then move on to the next set of blocks for A002 and so on. 

I obviously would need to select the Prefix first and have the option to type the number sequence to begin with.

 

Hopefully I made sense explaining this. I was never good at programming, code, C+ and all that stuff barely passed the class with a D+ and shook the teachers hand said thank you and left quickly. So looking at this is truly like speaking Klingon for me lolol. 

0 Likes
Accepted solutions (2)
1,825 Views
22 Replies
Replies (22)
Message 2 of 23

Moshe-A
Mentor
Mentor

@rfigueroa24PK4  hi,

 

Check this one 😀

 

The concept is to select set of pairs blocks (wire-in, wire-out) together

did not understand who pairs with power-in so for now it is ignore

 

enjoy

Moshe

 

 

(defun c:wiretag (/ _initget_options _prompt_options askKword  _format setAttribValue ; local functions
		    prefix n ss elist0 elist1 ename0 ename1)

 ; anonymous functions
 (setq _initget_options (lambda (l) (substr (apply 'strcat (mapcar (function (lambda (k) (strcat " " k " " (strcase k)))) l)) 2)))
 (setq _prompt_options  (lambda (l) (substr (apply 'strcat (mapcar (function (lambda (k) (strcat "/" (strcase k)))) l)) 2))) 

 
 (defun askKword (lst / ask)
  (initget (_initget_options lst))
  (setq ask (getkword (strcat "\nTag prefix " (_prompt_options lst) ": ")))
 ); askKword


 (defun _format (s l)
  (while (< (strlen s) l)
   (setq s (strcat "0" s))
  )
  s
 ); _format

  
 (defun setAttribValue ()
  (setpropertyvalue ename0 "wire" (strcat prefix (_format (itoa n) 3)))
  (setpropertyvalue ename1 "wire" (strcat prefix (_format (itoa n) 3))) 
 ); setAttribValue

  
 ; here start c:wiretag
 (if (and
       (setq prefix (askKword '("v" "a" "s" "p" "c" "n" "na" "nv" "rf")))
       (setq n (getint "\nStarting number: "))
     )
  (while (and
           (not (prompt "\nPick pairs: wire-in & wire-out..."))
	   (setq ss (ssget '((0 . "insert") (2 . "wire-in,wire-out") (66 . 1))))
	   (= (sslength ss) 2)
         )
   (setq elist0 (entget (setq ename0 (ssname ss 0))))
   (setq elist1 (entget (setq ename1 (ssname ss 1))))

   ; check block selection
   (cond
    ((and
      (eq (strcase (cdr (assoc '2 elist0))) "WIRE-IN")
      (eq (strcase (cdr (assoc '2 elist1))) "WIRE-OUT")
     )
     (setAttribValue)
    ); case
    ((and
      (eq (strcase (cdr (assoc '2 elist0))) "WIRE-OUT")
      (eq (strcase (cdr (assoc '2 elist1))) "WIRE-IN")
     )
     (setAttribValue)
    ); case
    ( t
     (princ "\ninvalid block selection.")
    ); case
   ); cond

   (setq n (1+ n))
  ); while 
 ); if

 (princ)
); c:wiretag

 

 

 

 

 

 

Message 3 of 23

john.uhden
Mentor
Mentor

@Moshe-A ,

I don't know if it works at all, but you are a very clever lisper.

John F. Uhden

0 Likes
Message 4 of 23

rfigueroa24PK4
Contributor
Contributor

Moshe-A

 

Moshe-A

Thank you very much, this worked wonderfully for the Wire-in and Wire-out blocks.
As for the Power-in. It is a single block that has 2 attributes, Wire1 and Wire2. Those 2 attributes are acting the same as Wire-in and Wire-out but on the exact same single block. The plan was for me to have a power cord on the schematic but when i extract the labels if it only has one wire label it would only print one label. So I created 2 wire labels in the block so it can extract 2.

rfigueroa24PK4_0-1721265071833.png

The attributes are the WIRE1 and WIRE2, their tags are WIRE_1 and WIRE_2.

0 Likes
Message 5 of 23

Moshe-A
Mentor
Mentor

Dear Great @john.uhden ,

 

Thank you very much, to get such a compliment from you this morning just made my day 😀 🙏

i guess the (_initget_options) and (_prompt_options) anonymous functions impressed you.

this is the first time i used this technique cause i never faced prompt with so many options with just 1-2 characters .

i was amazed my self on what came out 🤣

 

Have a nice day

Moshe

 

 

0 Likes
Message 6 of 23

Moshe-A
Mentor
Mentor

@rfigueroa24PK4 ,

 

power-in:

in order to make sure it is working 100%, i need to have your blocks. is there a reason why you are not posting them?

in your first post you said :

The power-in has a "WIRE 1" and "WIRE 2" Tag attribute

 

now you say:

The attributes are the WIRE1 and WIRE2, their tags are WIRE_1 and WIRE_2.

 

which is true?

 

wire-in & wire-out:

you select a pair and the attributes value say it have wire-in->"A001" and wire-out->"A001"

 

On power-in do you want the 2 attributes to have the same value?  you see, without an exact example from

you i am just guessing?!

 

Moshe

 

 

 

 

 

0 Likes
Message 7 of 23

Sea-Haven
Mentor
Mentor

@Moshe-A your welcome to use this I dont use initget anymore.

 

 

 

; here start c:wiretag
 (if (and
       (setq prefix (askKword '("v" "a" "s" "p" "c" "n" "na" "nv" "rf")))
       (setq n (getint "\nStarting number: "))
     )

(if (not AH:Butts)(load "Multi radio buttons.lsp")) ; loads the program if not loaded already
(if (and
       (setq prefix (ah:butts 1 "V" '("Please choose" "v" "a" "s" "p" "c" "n" "na" "nv" "rf")))
(setq n (getint "\nStarting number: "))
     )

 

SeaHaven_0-1721345035558.png

 

 

0 Likes
Message 8 of 23

rfigueroa24PK4
Contributor
Contributor

Moshe-A

 

I apologize, I wasnt sure if you wanted the blocks or not. I have attached them here. Hopefully once you open them they will make better sense than how I am trying to explain lol.

0 Likes
Message 9 of 23

rfigueroa24PK4
Contributor
Contributor

Also, I realized after a bit of testing that the lisp routine works perfectly if i bring in a New wire block, but does not work on existing blocks that are identical. And even if I bring in the block again to redefine it, the existing ones still don't work, just the new inserted block. Not sure what Im doing wrong.

0 Likes
Message 10 of 23

cadffm
Consultant
Consultant

Hi,

the problem is that the lisp selecting blockreference of block with names "wire-in" and "wire-out" ONLY,

but you are using dynamic block features and after you changed one dynamic parameter value,

the blockreferences are refering to other blocks (which are internal created and hidden of user eyes).

 

Test it:

Insert a new blockref,

Check the block name to what the reference refers:

Command: (alert (strcat "Blockname is: " (cdr(assoc 2 (entget(car(entsel)))))))

Change the dynamic property value (change the visibility state)

and check the (real) block name again.

Short: You need to update the code to run with dynamic blocks too.

 

 

Sebastian

0 Likes
Message 11 of 23

rfigueroa24PK4
Contributor
Contributor

Lol, to be 100% honest with you, I have absolutely no idea what you said. But Im assuming since you said the lisp needs to work with dynamic blocks, I changed the visibility as you requested and sure enough you are right. When i first insert it and leave it as is, the lisp routine works. But the moment I change the visibility state to a different connector it stops working.

0 Likes
Message 12 of 23

cadffm
Consultant
Consultant

 

 

@Moshe-A 

I have no idea whether that was intentional or not, but at least for other readers I would like to mention it here.

By formating the getkword string this way, you skipped the possibility to select the kwords by mouse inside the commandline or cursor menu, and it doesn't match the common AutoCAD command prompt syntax.

(getkword "\nSome text V/A/S/P/C/N/NA/NV/RF: ")

cadffm_5-1721399491791.png

 

vs

 

(getkword "\nSome text [V/A/S/P/C/N/NA/NV/RF]: ")

cadffm_6-1721399619424.png

 

 

(setq _prompt_options (lambda (l) (strcat "[" (substr (apply 'strcat (mapcar (function (lambda (k) (strcat "/" (strcase k)))) l)) 2) "]")))

 

 

 

Sebastian

0 Likes
Message 13 of 23

paullimapa
Mentor
Mentor
Accepted solution

FYI: DYNMODE needs to be set to either 1 or 3 for the cursor menu to appear


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 14 of 23

Moshe-A
Mentor
Mentor

@cadffm  hi,

 

yes you are absolutely right the "[" "]" where missing, thanks

 

Something not related to above 😀  (for all experts here)

think i found a bug in (vl-every)

the following function is for setting attributes value. when i call it with 2 blocks to set attribute on each, only the first block was modified. after a lot of tries including changing versions, i replaced (vl-every) with (mapcar) and it worked.

 

is this a known bug?

 

 

 

 

(setq _setAttribValue  (lambda (ents tags vals) (vl-every (function (lambda (ent tag val) (setpropertyvalue ent tag val))) ents tags vals)))

 

 

 

0 Likes
Message 15 of 23

Moshe-A
Mentor
Mentor

@rfigueroa24PK4 ,

 

OK lisp modified including power-in. i set wire_1 & wire_2  as equal values (same as wire-in & wire-out)

but you did not answer my question on that?!

 

Moshe

 

 

(defun c:wiretag (/ _initget_options _prompt_options _isDynamicBlock _isBlockValid setAttribValue _genValue _format askKword ; local functions
		    prefix n ss elist0 elist1 ename0 ename1)

 ; anonymous functions
 (setq _initget_options (lambda (l) (substr (apply 'strcat (mapcar (function (lambda (k) (strcat " " k " " (strcase k)))) l)) 2)))
 (setq _prompt_options  (lambda (l) (substr (apply 'strcat (mapcar (function (lambda (k) (strcat "/" (strcase k)))) l)) 2))) 
 (setq _isDynamicBlock  (lambda (l) (vl-every (function (lambda (ent) (= (getpropertyvalue ent "IsDynamicBlock") 1))) l)))
 (setq _isBlockValid    (lambda (ents names) (vl-every (function (lambda (ent name) (eq (strcase (getpropertyvalue ent "BlockTableRecord/Name")) name))) ents names)))
 (setq _setAttribValue  (lambda (ents tags vals) (vl-every (function (lambda (ent tag val) (setpropertyvalue ent tag val))) ents tags vals)))
 (setq _genValue        (lambda (l) (mapcar (function (lambda (n) (strcat prefix (_format (itoa n) 3)))) l)))

  
 (defun _format (s l)
  (while (< (strlen s) l)
   (setq s (strcat "0" s))
  )
  s
 ); _format
  
 (defun askKword (lst / ask)
  (initget (_initget_options lst))
   
  (if (setq ask (getkword (strcat "\nTag prefix [" (_prompt_options lst) "]: ")))
   (strcase ask)
  )
 ); askKword

   
 ; here start c:wiretag
 (if (and
       (setq prefix (askKword '("v" "a" "s" "p" "c" "n" "na" "nv" "rf")))
       (setq n (getint "\nStarting number: "))
     )
  (while (and
           (not (prompt "\nSelect pairs: wire-in + wire-out or power-in..."))
	   (setq ss (ssget '((0 . "insert") (2 . "wire-in,wire-out,power-in,`*U*") (66 . 1))))
	   (<= (sslength ss) 2)
         )
   (cond
    ((= (sslength ss) 1)
     (setq ename0 (ssname ss 0))
     (if (and
	   (_isDynamicBlock (list ename0))
           (_isBlockValid (list ename0) '("POWER-IN"))
	 )
      (_setAttribValue (list ename0 ename0) '("wire_1" "wire_2") (_genValue (list n n)))
     ); if
    ); case
    ((= (sslength ss) 2)
     (setq ename0 (ssname ss 0))  
     (setq ename1 (ssname ss 1))

     (if (and
	   (_isDynamicBlock (list ename0 ename1))
           (or
             (_isBlockValid (list ename0 ename1) '("WIRE-IN" "WIRE-OUT"))
             (_isBlockValid (list ename1 ename0) '("WIRE-IN" "WIRE-OUT"))
	   )
	 )
      (_setAttribValue (list ename0 ename1) '("WIRE" "WIRE") (_genValue (list n n)))
     ); if
    ); case
    ( t
     (princ "\ninvalid block(s) selection.")
    ); case
   ); cond
 
   (setq n (1+ n))
  ); while 
 ); if

 (princ)
); c:wiretag

 

0 Likes
Message 16 of 23

john.uhden
Mentor
Mentor

@Moshe-A ,

I'm really too dense to figure out what you are trying to do.

My use of vl-every and vl-some reveals that they return only either T or nil...

 

Command: (vl-every 'numberp '(1 2 3 4 5))

T

Command: (vl-every 'numberp '(1 2 3 4 5 "X"))
nil

Command: (vl-some 'numberp '(1 2 3 4 5 "X"))
T

John F. Uhden

0 Likes
Message 17 of 23

Moshe-A
Mentor
Mentor

yes i know that, in this case i do not mind the return value from (vl-every) i only want it to run on each item

0 Likes
Message 18 of 23

rfigueroa24PK4
Contributor
Contributor

Good morning Moshe_A

 

I tried the new lisp you created and it is working halfway. The wire-in block is labeling but not the wire-out and vice versa, the first one you click is getting the label not the second. And the power-in block is labeling wire_1 but not label_2. As for the question you mention I don't answer, could you please ask again because I may not be understanding you correctly, sorry.

 

rfigueroa24PK4_0-1721652905622.png

 

0 Likes
Message 19 of 23

Moshe-A
Mentor
Mentor

@rfigueroa24PK4 

 

this from message #6

On power-in do you want the 2 attributes to have the same value? 

maybe for you it clear? but you did not said it.

 

if that is the case then why 2 attributes on the same block holds the same value?

 

 

 

 

0 Likes
Message 20 of 23

rfigueroa24PK4
Contributor
Contributor

Yes on the power-in block both attributes should hold the same value. As stated before, the plan is once all blocks have their wire tags, I will extract all wire tags to create field labels. Since you require 1 label per end of wire I needed to put the wire tags somewhere so I made the block with 2 attributes to place them both there. Hopefully this makes sense now. In the end it should look like this screen shot.

 

rfigueroa24PK4_0-1721657797189.png

 

0 Likes