PDA

View Full Version : Looking for help / guidance writing a routine



thomas.stright
2006-02-03, 12:54 PM
Ok starting from zip, this is what I'm looking to accomplish...

1). Place elevation tag using Q-pen's elevation routine ( places mtext on current layer)

2). Select elevation leader. Select Q-pen pipe.

3). Get pipe layer name, create new layer with pipe layer name and append -elev to it.

4). Make new layer current.

5). Pick start point for leader, Pick 2nd point. Get mtext from step 1, place as leader text.

6) In the end have a Dot Leader with the mtext and leader on the new *-elev layer.




Whats the best way to start this? Do I need to have variables? I'm guessing yes....

This is how I'm starting... (good? bad?)







(defun c:elev1)
(command "style" "Romans" "romans.shx" "" "" "" "" "" "")
(setq lun (getvar "lunits"))
(setq pks (getvar "pickstyle"))
(command "pickstyle" "0")
(princ "nSelect only Pipe: ")

T.Willey
2006-02-03, 04:28 PM
Ok starting from zip, this is what I'm looking to accomplish...

1). Place elevation tag using Q-pen's elevation routine ( places mtext on current layer)

Can you call this from a lisp? If so then that would be great.


2). Select elevation leader. Select Q-pen pipe.

I would use "entget" to select objects if you only want one thing at a time.


3). Get pipe layer name, create new layer with pipe layer name and append -elev to it.
4). Make new layer current.

Get the objects layer thuogh the dxf code "8". Use "strcat" to add the two strings together. Use the layer command to make the new layer, and set it current.


5). Pick start point for leader, Pick 2nd point. Get mtext from step 1, place as leader text.

You can use the leader command, but back after step one, I would use "entlast" to get the mtext object, so that you can add the text here.


6) In the end have a Dot Leader with the mtext and leader on the new *-elev layer.

This will happen.

thomas.stright
2006-02-03, 07:09 PM
Can you call this from a lisp? If so then that would be great.Yes, This works


(command "_QPEN_ANOELV" pause "l")

This leaves me with the mtext placed

thomas.stright
2006-02-03, 07:17 PM
I would use "entget" to select objects if you only want one thing at a time.So now I need to select the object...correct?






(command "_QPEN_ANOELV" pause "l");;Use PD3D Elevate command
(setq pks (getvar "pickstyle"))
(command "pickstyle" "0");;Sets pickstyle
(princ "\nSelect only Pipe: ");;User Prompt
(setq pd3d (ssget '((0 . "QPEN_PD_ENTITY"))));;object to select

T.Willey
2006-02-03, 07:21 PM
Yup, but don't look at your old code to much. Or you can look at it, but don't follow it to hard. The selection I would use is "entsel".

But first you will want to set a variable to "entlast" so that you can have your mtext object saved somewhere.

T.Willey
2006-02-03, 08:24 PM
Here is a quick little one that might get you in the right direction.


(defun c:ElvLe (/ TextEnt Sel EntData Lay)

(command "_QPEN_ANOELV" pause "l")
;(command "_.Mtext" pause pause "Testing" "")
(setq TextEnt (entlast))
(if (setq Sel (entsel "\n Select pipe: "))
(progn
(setq EntData (entget (car Sel)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)
(princ)
)

Opie
2006-02-03, 08:37 PM
Here is a quick little one that might get you in the right direction.


(defun c:ElvLe (/ TextEnt Sel EntData Lay)

(command "_QPEN_ANOELV" pause "l")
;(command "_.Mtext" pause pause "Testing" "")
(setq TextEnt (entlast))
(if (setq Sel (entsel "\n Select pipe: "))
(progn
(setq EntData (entget (car Sel)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)
(princ)
)

This will error if the new layer is already in the drawing and frozen.

T.Willey
2006-02-03, 08:43 PM
This will error if the new layer is already in the drawing

It won't if you use the make option of the layer command.

This will error if the new layer is.. frozen.
Yes.
This is a simple example, for he wants to learn as he goes along, but thanks for pointing that out. I don't usually use commands in lisp anymore, unless I have to.

Opie
2006-02-03, 08:48 PM
It won't if you use the make option of the layer command.

Yes.
This is a simple example, for he wants to learn as he goes along, but thanks for pointing that out. I don't usually use commands in lisp anymore, unless I have to.
That is why I said frozen. ;) I just wanted to point that bit of information for the OP.

And I know that this is a learning experience for thomas.

T.Willey
2006-02-03, 08:58 PM
That is why I said frozen. ;) I just wanted to point that bit of information for the OP.

And I know that this is a learning experience for thomas.
I got you now. I'm slow :grin:. You meant if it was frozen in the current drawing, which means that is already in the drawing, and that was the ONLY point (frozen). I thought you were making two points.

Opie
2006-02-03, 09:01 PM
I got you now. I'm slow :grin:. You meant if it was frozen in the current drawing, which means that is already in the drawing, and that was the ONLY point (frozen). I thought you were making two points.
Not really. I'm pointless most of the time. Just ask my MBH.

thomas.stright
2006-02-06, 11:35 AM
Just to make sure I'm understanding this,,,,




(defun c:ElvLe (/ TextEnt Sel EntData Lay)

(command "_QPEN_ANOELV" pause "l");;QPEN Command
;(command "_.Mtext" pause pause "Testing" "")
(setq TextEnt (entlast));;Selecting last entity
(if (setq Sel (entsel "\n Select pipe: "))
(progn
(setq EntData (entget (car Sel)));;var for slected entity
(setq Lay (cdr (assoc 8 EntData)));;detting layer of selected entity
(command "_.layer" "_m" (strcat Lay "-elev") "");;creating new layer
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "");;starting leader,using last text
)
)
(princ)
)


Are the comments correct?

Opie
2006-02-06, 02:20 PM
Just to make sure I'm understanding this,,,,




(defun c:ElvLe (/ TextEnt Sel EntData Lay)

(command "_QPEN_ANOELV" pause "l");;QPEN Command
;(command "_.Mtext" pause pause "Testing" "")
(setq TextEnt (entlast));;Selecting last entity
(if (setq Sel (entsel "\n Select pipe: "))
(progn
(setq EntData (entget (car Sel)));;var for slected entity
(setq Lay (cdr (assoc 8 EntData)));;detting layer of selected entity
(command "_.layer" "_m" (strcat Lay "-elev") "");;creating new layer
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "");;starting leader,using last text
)
)
(princ)
)


Are the comments correct?
Those comments look correct. ;)

thomas.stright
2006-02-06, 02:26 PM
Why am I getting this when trying to test this?

; error: malformed list on input

Opie
2006-02-06, 02:34 PM
Why am I getting this when trying to test this?

; error: malformed list on input
The only thing I cannot test for you is this line.

(command "_QPEN_ANOELV" pause "l");;QPEN Command

I have run the code. I noticed that it creates a second MTEXT object. But I do not get any errors.

Have you used the Visual Lisp interactive development environment (VLIDE)? This can help you step through your code to see what is happening. Search the AutoLISP, Visual LISP, and DXF help file for Debug Menu (VLISP)

T.Willey
2006-02-06, 04:17 PM
Why am I getting this when trying to test this?

; error: malformed list on input
I just copy/paste it from your post into CAD and I didn't get that message. If you are loading for a lisp file, maybe you have other things happening in the file. Try to just copy/paste into CAD from my, or your, post, and then test the command.

The comments look good to me also.

thomas.stright
2006-02-06, 04:56 PM
The only thing I cannot test for you is this line.

(command "_QPEN_ANOELV" pause "l");;QPEN Command

I have run the code. I noticed that it creates a second MTEXT object. But I do not get any errors.

Have you used the Visual Lisp interactive development environment (VLIDE)? This can help you step through your code to see what is happening. Search the AutoLISP, Visual LISP, and DXF help file for Debug Menu (VLISP)Yes, I have been using VLIDE. That helps alot...

thomas.stright
2006-02-06, 05:16 PM
I think the Qpen command


(command "_QPEN_ANOELV" pause "l")

Does not like being included in the routine, What we were doing before was running the elevation command then starting the routine to select the pipe... I believe this will be a two step process, Of placing the elevation then placing the elevation text on the layer we need to create.

T.Willey
2006-02-06, 05:28 PM
I think the Qpen command


(command "_QPEN_ANOELV" pause "l")

Does not like being included in the routine, What we were doing before was running the elevation command then starting the routine to select the pipe... I believe this will be a two step process, Of placing the elevation then placing the elevation text on the layer we need to create.
Let us know what happens after your testing this theory.

thomas.stright
2006-02-06, 06:29 PM
I'm trying to select the pipe using...



(defun c:ElvLe (/ TextEnt Sel EntData Lay)
(if (setq Sel (entsel "\n Select pipe: "))
(setq Sel (entget (0 . "QPEN_PD_ENTITY")))
(progn
;;(setq EntData (entget (car Sel)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)
(princ)

I don't think I'm using this right..


(if (setq Sel (entsel "\n Select pipe: "))
(setq Sel (entget (0 . "QPEN_PD_ENTITY")))

T.Willey
2006-02-06, 06:44 PM
You will select the object (Pipe) with "entsel", you will then get all the dxf codes with "entget". If you only want to be select an object, then I would use "ssget" instead of "entsel". You can set up "ssget" so you can only select once, and not with a window. I think that is what you are after, so your "if" statement would look like.


(if (setq ss (ssget ":S:E" '((0 . "QPEN_PD_ENTITY"))))
(progn
(setq EntData (entget (ssname ss 0)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)

Does this work for you?

thomas.stright
2006-02-06, 06:53 PM
Does this work for you?It makes the layer, Draws the leader then stops before it picks the mtext. I get a "nil" response like it's not seeing the mtext that was placed. would it be easier to pick the text?

T.Willey
2006-02-06, 07:32 PM
would it be easier to pick the text?
Yup. I like it when you don't have to pick other objects, so I try to code as much no user interface as possible. You can pick the text, then grab the text value, then delete it, then issue the leader command. Let us know how it goes.

thomas.stright
2006-02-07, 11:32 AM
Yup. I like it when you don't have to pick other objects, so I try to code as much no user interface as possible. You can pick the text, then grab the text value, then delete it, then issue the leader command. Let us know how it goes.Users not having to pick would be ok...

I thought this

(cdr (assoc 1 (entget TextEnt)

was suppose to pick the last text?

Opie
2006-02-07, 02:05 PM
Users not having to pick would be ok...

I thought this

(cdr (assoc 1 (entget TextEnt)

was suppose to pick the last text?
That bit of code extracts the string itself from a TEXT or MTEXT entity. However, if the string for an MTEXT entity is greater than 250 characters, the string will be broken out across one or more group code 3 with the last chunk being a group code 1 containing fewer than 250 characters.

I hope that makes sense.

thomas.stright
2006-02-07, 02:28 PM
I understand the (entget TxtEnt), It just seems to not grab the mtext placed by the annoelve command...

Opie
2006-02-07, 02:36 PM
I understand the (entget TxtEnt), It just seems to not grab the mtext placed by the annoelve command...
Have a look at what the TxtEnt was assigned to in this post. It appears that it has not been assigned in Tim's latest code post.

thomas.stright
2006-02-07, 03:47 PM
Have a look at what the TxtEnt was assigned to in this post. It appears that it has not been assigned in Tim's latest code post.
As in this?


(defun c:ElvLe (/ TextEnt Sel EntData Lay)

T.Willey
2006-02-07, 04:12 PM
As in this?


(defun c:ElvLe (/ TextEnt Sel EntData Lay)
This only tells you what variables will be local (used only by this routines). The place that assigned the "TextEnt" variable was this line of code


(setq TextEnt (entlast))

The last bit of code that I posted was only the if statement. You will have to look at the first code I posted, and combind it with the last bit of code I posted. I hope that makes sense.

Opie
2006-02-07, 04:19 PM
As in this?


(defun c:ElvLe (/ TextEnt Sel EntData Lay)

Sorry, wrong one. I was speaking of this one.


(setq TextEnt (entlast));;Selecting last entity

The one you mention is the initial declaration of the routine. The defun tells AutoCAD to execute all of the following functions. The c: allows the user to type the command at the command prompt without having to surround it with parenthesis. The ElvLe is the name of the command. The list of declared variables, (/ TextEnt Sel EntData Lay) are local variables. Once the routine is completed those variables will not contain any values.

The code I posted here actually assigns the last entity to the variable TextEnt. Before, your code was not assigning anything to this variable but was attempting to get a value from it. You will need to assign some data to the variable

I hope this helps. ;)

thomas.stright
2006-02-07, 04:35 PM
So it needs to be before the enget statement. Correct?



(if (setq ss (ssget ":S:E" '((0 . "QPEN_PD_ENTITY"))))
(progn
(setq EntData (entget (ssname ss 0)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(setq TextEnt (entlast))
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)

T.Willey
2006-02-07, 04:45 PM
It can be there. The statement is going to get the last entity added into the drawings database. I'm assuming that it is mtext, as you said you run the command to make the mtext first. You might want to add a check to make sure that the object is mtext, and if not, then maybe you can select it. Something like.


(setq TextEnt (entlast))
(if (/= (type TextEnt) 'MTEXT)
(setq TextEnt (car (entsel "\n Select MText object: ")))
)

thomas.stright
2006-02-07, 05:01 PM
Ok... I'm thinking that I follow you on this.
So if the last object is not mtext this will allow you to select the text to use.



(if (setq ss (ssget ":S:E" '((0 . "QPEN_PD_ENTITY"))))
(progn
(setq EntData (entget (ssname ss 0)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(setq TextEnt (entlast))
(if (/= (type TextEnt) 'MTEXT)
(setq TextEnt (car (entsel "\n Select MText object: ")))
)
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)

T.Willey
2006-02-07, 05:06 PM
Ok... I'm thinking that I follow you on this.
So if the last object is not mtext this will allow you to select the text to use.

You are correct. Wow, I had to make my sentance at least 10 characters long.

thomas.stright
2006-02-07, 05:11 PM
Great... I'm learning something....After beating myself with a rock...lol

T.Willey
2006-02-07, 05:18 PM
Great... I'm learning something..
That is good.

..After beating myself with a rock...lol
This is not.
At leat you still have your sense of humor. :grin:

thomas.stright
2006-02-07, 05:31 PM
Everything checks out in VLIDE til I place this in


(defun c:ElvLe (/ TextEnt EntData Lay)

Opie
2006-02-07, 05:38 PM
Everything checks out in VLIDE til I place this in


(defun c:ElvLe (/ TextEnt EntData Lay)
What is the error the VLIDE is giving you?

thomas.stright
2006-02-07, 05:39 PM
What is the error the VLIDE is giving you?[CHECKING TEXT ElvLe.lsp loading... SELECTION]
; error: malformed list on input
; Check done.

Opie
2006-02-07, 05:42 PM
[CHECKING TEXT ElvLe.lsp loading... SELECTION]
; error: malformed list on input
; Check done.
Did you place a closing parenthesis?

thomas.stright
2006-02-07, 05:46 PM
Did you place a closing parenthesis?On the defun line?

edit... Missing at the end I believe

Opie
2006-02-07, 05:54 PM
On the defun line?

edit... Missing at the end I believe
Yes, at the very end of the routine.

thomas.stright
2006-02-07, 05:55 PM
Yeah... It works with a minor issue



(defun c:ElvLe (/ TextEnt EntData Lay)

(if (setq ss (ssget ":S:E" '((0 . "QPEN_PD_ENTITY"))))
(progn
(setq EntData (entget (ssname ss 0)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(setq TextEnt (entlast))
(if (/= (type TextEnt) 'MTEXT)
(setq TextEnt (car (entsel "\n Select MText object: ")))
)
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
)
)
)

Now I need it to erase the selected text, And have the leader use a style.

T.Willey
2006-02-07, 05:55 PM
Did you get it to work? If not then post the code, and we can look at it to see if we can see anything.

T.Willey
2006-02-07, 05:57 PM
To erase the text, add this line at toward the end
(entdel TextEnt)
To use a certain dim style for the leader, you will have to set that current prior to issuing the leader command, or change it after you draw it. I think the former will be easier.

thomas.stright
2006-02-07, 06:03 PM
Should I use the command function?


(command "-dimstyle" "r" "Dot" "dimtad" "1"
"_leader" pause pause "" ""
"c" elvle "erase" elvle ""
)

??

T.Willey
2006-02-07, 06:06 PM
I wouldn't use the whole thing, but the part that sets the dim style to the one you want, you can use. We already have code to draw the leader, so we don't need that part. Looks like all you need is


(command "_.-dimstyle" "_r" "Dot")

If it exist in the drawing already.

thomas.stright
2006-02-07, 06:13 PM
I wouldn't use the whole thing, but the part that sets the dim style to the one you want, you can use. We already have code to draw the leader, so we don't need that part. Looks like all you need is


(command "_.-dimstyle" "_r" "Dot")

If it exist in the drawing already.Which it does....

T.Willey
2006-02-07, 06:17 PM
So now all you have to do is put it all together and see if it works. Let us know, and if it does error, post what the error is.

thomas.stright
2006-02-07, 06:20 PM
Success!! Works very well.

A very big thanks to Tim!

And to Opie....

This seems addictive...

T.Willey
2006-02-07, 06:26 PM
Success!! Works very well.

A very big thanks to Tim!

And to Opie....

This seems addictive...
Glad to hear it!! and yes it is VERY addictive once you see what you CAN do with lisp, or other programming languages.

T.Willey
2006-02-07, 06:30 PM
Another thing you may want to do is add


(command "_.undo" "_end")
(command "_.undo" "_group")

At the very beginning, and


(command "_.undo" "_end")

To the very end of your code. What this will do is, let one undo, undo your whole routine. Very helpful when you have more than one command in your routine. I add those features to almost all my routines.

thomas.stright
2006-02-07, 07:00 PM
Thats a good idea...

So the final code (at least for now) is



(defun c:ElvLe (/ TextEnt EntData Lay)

(command "_.undo" "_end")
(command "_.undo" "_group")
(if (setq ss (ssget ":S:E" '((0 . "QPEN_PD_ENTITY"))))
(progn
(setq EntData (entget (ssname ss 0)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(setq TextEnt (entlast))
(if (/= (type TextEnt) 'MTEXT)
(setq TextEnt (car (entsel "\n Select MText object: ")))
)
(command "_.-dimstyle" "_r" "Dot")
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
(entdel TextEnt)
(command "_.undo" "_end")
)
)
)

T.Willey
2006-02-07, 07:17 PM
One small correction.


(defun c:ElvLe (/ TextEnt EntData Lay)

(command "_.undo" "_end")
(command "_.undo" "_group")
(if (setq ss (ssget ":S:E" '((0 . "QPEN_PD_ENTITY"))))
(progn
(setq EntData (entget (ssname ss 0)))
(setq Lay (cdr (assoc 8 EntData)))
(command "_.layer" "_m" (strcat Lay "-elev") "")
(setq TextEnt (entlast))
(if (/= (type TextEnt) 'MTEXT)
(setq TextEnt (car (entsel "\n Select MText object: ")))
)
(command "_.-dimstyle" "_r" "Dot")
(command "_.leader" pause pause "" (cdr (assoc 1 (entget TextEnt))) "")
(entdel TextEnt)
)
)
(command "_.undo" "_end")
)


I moved the last undo end outside of the if statement. You want to end the undo no matter what happens, so with it located where it is now, it does not depend on anything happening to work.

Opie
2006-02-07, 07:22 PM
Success!! Works very well.

A very big thanks to Tim!

And to Opie....

This seems addictive...
Your welcome. ;) Welcome to the dark side. :twisted:

thomas.stright
2006-02-07, 07:31 PM
Well I will say I have learned at lot thanks to both of you.

I'll move the last undo... I've been using N. Poleshchuk's Developers guide to autolisp. Is there something else that would also help?

T.Willey
2006-02-07, 07:54 PM
I've learned mostly just coding, with the help files, and NG's like this one, and the Autodesk Customization (http://discussion.autodesk.com/forum.jspa?forumID=130), and now http://www.theSwamp.org. There is http://www.afralisp.co.za/ which is helpful also. I look at all post, and then see if I understand what they are doing, and if it looks helpful, you could try and rewrite it, on your own, using their code as a guide.