Jump to content

Learning Lisp "Polyline Width"


RubberDinero

Recommended Posts

No matter what I try, i keep getting an "Invalid Option Keyword". Here is what i have so far. don't know why i can't make it work.

 

(defun c:px2 ( / cmd ent enx ped pw1 pkw )
   (setvar 'errno 0)
   (while (/= 52 (getvar 'errno))
       (setvar 'errno 0)
       (setq ent (car (entsel "\nSelect polyline <exit>: ")))
       (cond
           (   (= 7 (getvar 'errno))
               (prompt "\nMissed, try again.")
           )
           (   (null ent)
               (prompt "\nExit.")
           )
           (   (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent)))))
               (prompt "\nSelected object is not an LWPolyline.")
           )
           (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx)))))))
               (prompt "\nSelected polyline is on a locked layer.")
           )
           (   (setq cmd (getvar 'cmdecho)
                     ped (getvar 'peditaccept)
               )
               (setvar 'cmdecho 0)
               (setvar 'peditaccept 1)
	[b][color="red"][size="3"](if (= (cdr (assoc 43 enx)) nil)
		(if (= (cdr (assoc 41 enx)) (cdr (assoc 40 enx)))
			(setq pw1 (cdr (assoc 40 enx)))
			((initget "Start End")
			 (setq pkw (getkword "\nMatch Starting or Ending Width? [start/End]: "))
				(cond
					((= pkw "S") (setq pw1 (cdr (assoc 40 enx))))
					((= pkw "E") (setq pw1 (cdr (assoc 41 enx))))
				)
			)
		)
		(setq pw1 (cdr (assoc 43 enx)))
	)[/size][/color][/b]
               (command
                   "_.explode" ent
                   "_.pedit" "_m" "_p" "" "_w" pw1 ""
               )
               (setvar 'peditaccept ped)
               (setvar 'cmdecho cmd)
           )
       )
   )
   (princ)
)

 

I'm able to click on Start or End, but doing so will give me the error. I've also tried typing S s E e Start START End END but i keep getting the error.

I've also tried localizing the strings i.e.

[color="red"][size="3"](initget "Start End _(cdr (assoc 40 enx)) (cdr (assoc 41 enx))")[/size][/color]

but that also doesn't allow any option to be correct. same error no matter what i type.

 

I'm all out of ideas.

Link to comment
Share on other sites

  • Replies 29
  • Created
  • Last Reply

Top Posters In This Topic

  • RubberDinero

    14

  • Grrr

    8

  • Lee Mac

    4

  • Roy_043

    2

Try the following (modified RED code fragment from your post) :

(if (= (cdr (assoc 43 enx)) nil)
(if (= (cdr (assoc 41 enx)) (cdr (assoc 40 enx)))
	(setq pw1 (cdr (assoc 40 enx)))
	(progn
		(initget "Start End S E")
		(setq pkw (strcase (getkword "\nMatch Starting or Ending Width? [start/End]: ")))
		(cond
			((or (= pkw "START")(= pkw "S")) (setq pw1 (cdr (assoc 40 enx))))
			((or (= pkw "END")(= pkw "E")) (setq pw1 (cdr (assoc 41 enx))))
		)
	); progn
)
(setq pw1 (cdr (assoc 43 enx)))
)

Link to comment
Share on other sites

@ Grrr:

Your use of (initget ...) is not correct.

See:

http://docs.autodesk.com/ACD/2011/ENU/filesALR/WS1a9193826455f5ff1a32d8d10ebc6b7ccc-69da.htm

 

Note that (getkword ...) can also return nil.

 

Thanks, I was sure about that.. so I rely on the (cond) below it. Its not the first time I do this mistake, I'm just lazy to analyse this particular problem.

Link to comment
Share on other sites

Try the following (modified RED code fragment from your post)

 

Wow, that worked great! The lisp is now complete!

 

I'll need to study how you did it and learn from it! Thanks

 

To anyone that runs into this thread looking for a fail-proof way to "Unjoin a polyline" "explode a polyline while keeping the width"

 

here is the Lisp

(defun c:px ( / cmd ent enx ped pw1 pkw )
   (setvar 'errno 0)
   (while (/= 52 (getvar 'errno))
       (setvar 'errno 0)
       (setq ent (car (entsel "\nSelect polyline <exit>: ")))
       (cond
           (   (= 7 (getvar 'errno))
               (prompt "\nMissed, try again.")
           )
           (   (null ent)
               (prompt "\nExit.")
           )
           (   (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent)))))
               (prompt "\nSelected object is not an LWPolyline.")
           )
           (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx)))))))
               (prompt "\nSelected polyline is on a locked layer.")
           )
           (   (setq cmd (getvar 'cmdecho)
                     ped (getvar 'peditaccept)
               )
               (setvar 'cmdecho 0)
               (setvar 'peditaccept 1)
	(if (= (cdr (assoc 43 enx)) nil)
		(if (= (cdr (assoc 41 enx)) (cdr (assoc 40 enx)))
			(setq pw1 (cdr (assoc 40 enx)))
				(progn
					(initget "Start End S E")
					(setq pkw (strcase (getkword "\nMatch Starting or Ending Width? [start/End]: ")))
			(cond
			((or (= pkw "START")(= pkw "S")) (setq pw1 (cdr (assoc 40 enx))))
			((or (= pkw "END")(= pkw "E")) (setq pw1 (cdr (assoc 41 enx))))
		)
	); progn
)
(setq pw1 (cdr (assoc 43 enx)))
)
               (command
                   "_.explode" ent
                   "_.pedit" "_m" "_p" "" "_w" pw1 ""
               )
               (setvar 'peditaccept ped)
               (setvar 'cmdecho cmd)
           )
       )
   )
   (princ)
)

Link to comment
Share on other sites

Wow, that worked great! The lisp is now complete!

 

I'll need to study how you did it and learn from it! Thanks

 

You're wellcome. For a quick/successful start with LISP I would suggest you to read/practice with these functions: if , cond , and , or , not , eq , while , repeat

So later you would know how to properly structure your codes (by using functions for getting user input - like getkword/getstring/getpoint/getreal ...)

... and manipulating it.

Link to comment
Share on other sites

@ Grrr: you are missing several issues.

For one thing your code cannot cope with a nil return from (getkword). It would crash as (strcase) expects string input. And, contrary to what you say, your (cond) does not have a statement to handle pkw=nil, which would be required since the rest of the code relies on a valid value for pw1.

(progn
 (initget "Start End")
 (if (= "End" (getkword "\nMatch Starting or Ending Width? End/<Start>: "))
   (setq pw1 (cdr (assoc 41 enx))) ; User entered "E", "e", "end", "EN" or ... (no need for strcase).
   (setq pw1 (cdr (assoc 40 enx))) ; User pressed Enter or entered "S", "s", "start", "STA" or ...
 )
)

Link to comment
Share on other sites

(progn
 (initget "Start End")
 (if (= "End" (getkword "\nMatch Starting or Ending Width? End/<Start>: "))
   (setq pw1 (cdr (assoc 41 enx))) ; User entered "E", "e", "end", "EN" or ... (no need for strcase).
   (setq pw1 (cdr (assoc 40 enx))) ; User pressed Enter or entered "S", "s", "start", "STA" or ...
 )
)

 

That did work even better! I tried Grrr's code by just pressing "Enter" and it did fail. with your code, I modified the wording a bit, it defaults to Starting by pressing enter.

(defun c:px2 ( / cmd ent enx ped pw1 pkw pwt )
   (setvar 'errno 0)
   (while (/= 52 (getvar 'errno))
       (setvar 'errno 0)
       (setq ent (car (entsel "\nSelect polyline <exit>: ")))
       (cond
           (   (= 7 (getvar 'errno))
               (prompt "\nMissed, try again.")
           )
           (   (null ent)
               (prompt "\nExit.")
           )
           (   (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent)))))
               (prompt "\nSelected object is not an LWPolyline.")
           )
           (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx)))))))
               (prompt "\nSelected polyline is on a locked layer.")
           )
           (   (setq cmd (getvar 'cmdecho)
                     ped (getvar 'peditaccept)
               )
               (setvar 'cmdecho 0)
               (setvar 'peditaccept 1)
	(if (= (cdr (assoc 43 enx)) nil)
		(if (= (cdr (assoc 41 enx)) (cdr (assoc 40 enx)))
			(setq pw1 (cdr (assoc 40 enx)))
				[b][color="red"](progn
				  (initget "Start End")
				  (if (= "End" (getkword "\nMatch Starting or Ending Width? [start/End]:<Start> "))
				    (setq pw1 (cdr (assoc 41 enx))) ; User entered "E", "e", "end", "EN" or ... (no need for strcase).
				    (setq pw1 (cdr (assoc 40 enx))) ; User pressed Enter or entered "S", "s", "start", "STA" or ...
				  )
				)[/color][/b]
)
(setq pw1 (cdr (assoc 43 enx)))
)
               (command
                   "_.explode" ent
                   "_.pedit" "_m" "_p" "" "_w" pw1 ""
               )
               (setvar 'peditaccept ped)
               (setvar 'cmdecho cmd)
           )
       )
   )
   (princ)
)

Link to comment
Share on other sites

@ Grrr: you are missing several issues.

For one thing your code cannot cope with a nil return from (getkword). It would crash as (strcase) expects string input. And, contrary to what you say, your (cond) does not have a statement to handle pkw=nil, which would be required since the rest of the code relies on a valid value for pw1.

(progn
 (initget "Start End")
 (if (= "End" (getkword "\nMatch Starting or Ending Width? End/<Start>: "))
   (setq pw1 (cdr (assoc 41 enx))) ; User entered "E", "e", "end", "EN" or ... (no need for strcase).
   (setq pw1 (cdr (assoc 40 enx))) ; User pressed Enter or entered "S", "s", "start", "STA" or ...
 )
)

 

Thanks for the constructive criticism Roy,

Perhaps I don't analyse deep enough the solutions I'm posting (usually I use initget with bit 1 to prevent user from pressing ENTER). Your example seems perfect for this case, however I try to avoid using if within initget, and use instead (practice with) cond - just in case we would had more than 2 options:

(defun c:test ( / sUndo cmd ent enx ped pw1 pkw pwt *ans*)
(setq sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'StartUndoMark))
(setvar 'errno 0)
(while (/= 52 (getvar 'errno))
	(setvar 'errno 0)
	(setq ent (car (entsel "\nSelect polyline <exit>: ")))
	(cond
		(   (= 7 (getvar 'errno))
			(prompt "\nMissed, try again.")
		)
		(   (null ent)
			(prompt "\nExit.")
		)
		(   (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent)))))
			(prompt "\nSelected object is not an LWPolyline.")
		)
		(   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx)))))))
			(prompt "\nSelected polyline is on a locked layer.")
		)
		(   (setq cmd (getvar 'cmdecho)
			ped (getvar 'peditaccept)
		)
		(setvar 'cmdecho 0)
		(setvar 'peditaccept 1)
		[color="red"](if (not (assoc 43 enx))
			(cond
				((= (cdr (assoc 41 enx)) (cdr (assoc 40 enx)))
					(setq pw1 (cdr (assoc 40 enx)))
				)
				(T
					(or *ans* (setq *ans* "Starting")) ; Used http://www.lee-mac.com/promptwithdefault.html Dynamic Default Version2
					(initget "Starting Ending Value") 
					(setq *ans* (cond ((getkword (strcat "\nMatch Starting or Ending Width or specify a Value [start/End/Value] ? <" *ans* ">: "))) ( *ans* )))
					(cond
						((wcmatch *ans* "S*")
							(setq pw1 (cdr (assoc 40 enx)))
						)
						((wcmatch *ans* "E*")
							(setq pw1 (cdr (assoc 41 enx)))
						)
						((wcmatch *ans* "V*")
							(initget (+ 1 4))
							(setq pw1 (getreal "\nSpecify width value: "))
						)
					)
				)
			)
			(setq pw1 (cdr (assoc 43 enx)))
		)[/color]
		(if pw1 
			(command
				"_.explode" ent
				"_.pedit" "_m" "_p" "" "_w" pw1 ""
			)
		)
		(setvar 'peditaccept ped)
		(setvar 'cmdecho cmd)
		)
	)
)
(if sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'EndUndoMark))
(princ)
)(vl-load-com)(princ)

Lee mac's website always come to the rescue.

Link to comment
Share on other sites

Grrr!!! your new code made possible what i had in mind! but i felt i had already overstepped my welcome with request! But thanks to your latest response, i was able to add what i wanted to add but was getting error-ed out.

 

(defun c:px2 ( / sUndo cmd ent enx ped pw1 pkw *ans*)
(setq sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'StartUndoMark))
(setvar 'errno 0)
(while (/= 52 (getvar 'errno))
	(setvar 'errno 0)
	(setq ent (car (entsel "\nSelect polyline <exit>: ")))
	(cond
		(   (= 7 (getvar 'errno))
			(prompt "\nMissed, try again.")
		)
		(   (null ent)
			(prompt "\nExit.")
		)
		(   (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent)))))
			(prompt "\nSelected object is not an LWPolyline.")
		)
		(   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx)))))))
			(prompt "\nSelected polyline is on a locked layer.")
		)
		(   (setq cmd (getvar 'cmdecho)
			ped (getvar 'peditaccept)
		)
		(setvar 'cmdecho 0)
		(setvar 'peditaccept 1)
		(if (not (assoc 43 enx))
			(cond
				((= (cdr (assoc 41 enx)) (cdr (assoc 40 enx)))
					(setq pw1 (cdr (assoc 40 enx)))
				)
				(T
					(or *ans* (setq *ans* "Starting")) ; Used http://www.lee-mac.com/promptwithdefault.html Dynamic Default Version2
					(initget "Starting Ending Value") 
					(setq *ans* (cond ((getkword
(strcat [color="red"]"\nStarting Width is " (rtos (cdr (assoc 40 enx))) ". Ending Width is " (rtos (cdr (assoc 41 enx)))[/color]". Match Starting or Ending Width or specify a Value [start/End/Value] ? <" *ans* ">: "))) ( *ans* )))
					(cond
						((wcmatch *ans* "S*")
							(setq pw1 (cdr (assoc 40 enx)))
						)
						((wcmatch *ans* "E*")
							(setq pw1 (cdr (assoc 41 enx)))
						)
						((wcmatch *ans* "V*")
							(initget (+ 1 4))
							(setq pw1 (getreal "\nSpecify width value: "))
						)
					)
				)
			)
			(setq pw1 (cdr (assoc 43 enx)))
		)
		(if pw1 
			(command
				"_.explode" ent
				"_.pedit" "_m" "_p" "" "_w" pw1 ""
			)
		)
		(setvar 'peditaccept ped)
		(setvar 'cmdecho cmd)
		)
	)
)
(if sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'EndUndoMark))
(princ)
)(vl-load-com)(princ)

 

I don't know why when i added the (strcat, the lisp would error out on me no matter where in the code i placed it.

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