TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: ELOQUINTET on July 26, 2005, 10:16:14 AM
-
i think i should explain what i'm trying to acheive. we have a custom program for drawing our shade elevations but once they are drawn they are not really that friendly to do little tweaks to. when i need to stretch the elvation i don't want to have to go back through the dialogue and redraw it. one of the really annoying things is we have abbreviations for shadecloth (s.c.) and shade opening width (s.o.w.) but you will see in my example that when you stretch the elevation they don't stay centered. i have been using tracking to move them but it would be nice to be able to have a lisp do it for me.
here's basically what i'm trying to do:
pick the text using the node as the point
then move the text to the midpoint of the dimension line
then move the text down 3-1/2
see lisp and image below:
take it easy on me guys remember this is my first try :oops:
(defun C:mto ()
(setq p1 (getpoint "pickpoint-1"));\;
(setvar "osmode" 2)
(setq p2 (getpoint "pickpoint-2"));\;
(command "move" p1 p2)
(command "move" "p" @ 3.5))
(setvar "osmode" 127)
(princ)
)
(http://www.theswamp.org/screens/dan/lisp%20questions/mto.JPG)
-
maybe i am trying to write this too much like a macro. the idea originated from a macro we have for doing something else, gotta start somewhere :roll:
-
You could just grab the text like this
(entget (car (entsel)))
That will give you a list of dxf info in the text.
You'll need to set up variables. One for the above and one for the ename of the object:
(car (entsel))
Then you need to find out if the text justification is > 0. Is (73 . 0) and (72 . 0). Depending on your findings, you'll need to change group code 10 or 11.
You can use mapcar and a list:
(mapcar '- (list 0.0 3.0 0.0) (cdr (dxf code 11)))
Substitute its results into the list using
(subst newlist oldlist elist)
Then make the mod hold
(entmod (above subst))
(entupd ename)
Try a couple of these things out.
-
Wow, wouldn't it be better to modify the dimension to include the text?
Just over ride the text with this. <>\XS.O.W.
Then stretch to your hearts content.
-
yes i agree cab and it is my intention to greatly improve this routine once i am capable. there are many shortcomings of it. another being that there is no option to not include the detail callouts because sometimes i have to piece a long elevation together. or the option to draw a long elevation would be great. and to be prompted for the beginning detail number and it would increment them left to right and the sheet number. the thought was good but now its time to expand it. daron you completely lost me. i'll read about the functions you mentioned and see if i can put something together thanks guys
-
I was thinking the same thing, but he's trying to learn lisp here. Shant we work with him with what he'd like to do. Sure, it's not to hard to program dimension mods either. Maybe Dan could write both, one at a time, of course.
-
some of the functions look familiar but i havent a clue how to figure out what youre asking me to figure out. heres what i have now. i can already use mark dimension override lisp to add whatever override i desire but i wanted to try to write something i would find useful but maybe this is too complicated for my first try what do ya think? :oops:
(defun C:mto ()
(entget (car entsel)))
(mapcar '- (list 0.0 3.0 0.0) cdr (dxf code 11)))
(subst newlist oldlist elist)
(entmod (above substr))
(entupd ename)
(princ)
-
i'm only on lesson 3 of stigs tutorial keep in mind :oops:
-
Dan, I purposely left out variables and actual working things for your benefit. If you leave it as is, this is what you end up with:
mto
user selects object. Nothing remembered.
mapcar crashes because cdr is not a list.
The rest of the routine dies.
Look into setq
Start off with (setq varname (entsel "\nPick something: "))
In the vlide, type that, then highlight it and pick the little microscope button.
Then try this:
(setq ename (car varname))
You should end up with a mostly useless block.
Next try:
(setq elist (entget ename))
This will return a list that has lots of information in it. Under the help files, look for the dxf area and find text. There you'll see lots of definitions for what the first number means as well as what the second items mean. You'll be looking for 10, 11, 72 and 73.
When you get a handle on that, we'll look into what mapcar can do for you or if we should even be using it.
-
daron heres what i have so far. it appears to me to be code 72. thanks for helpin out giving me hints. like you say doing is the only way to really learn this. i'm trying but you may have to hold my hand for awhile until the light clicks on. thanks for your patience
(defun C:mto (shade)
(setq varname (entsel "\nPick something: "))
(1020.19 934.72 0.0)) ;;when i inspected the above line i got this?
(setq ename (car varname))
(setq elist (entget ename))
(mapcar '- (list 0.0 3.0 0.0) cdr (dxf code 72)))
(subst newlist oldlist elist)
(entmod (above substr))
(entupd ename)
(princ)
-
i have a side question. i want to print out all of my lisps i've collected and gothrough and study them. i'm wondering what's the easiest way to print out all of the file in a folder. i remeber seeing something but cant remember right now?
-
Dan, when you inspect entsel by itself, you should get:
(<Entity name: 7eb06630> (1214.74 383.699 0.0))
The car is the Entity name and the cadr or cdr is the coordinates of pick point of the selection. This point is useless for your purposes.
What you want to get is the car of that entsel list, which still does nothing for you except give you readable information. When you collect the car of entsel, get the entity list -> entget. So, you need:
(setq varname (car (entsel "\Pick something: ")))
and
(setq elist (entget varname)).
Really, you should use something better than varname, like ename, since what you're collecting is and Entity NAME, which you'll need in order to update your object (entity).
Your mapcar is still not quite correct. Let's not work on that yet, but for extra credit, read the help file on mapcar and see if you can find why it'll fail as it's written. Oh, and the first line:
(defun c:mto (shade)
Shade will do nothing for you at this time and if shade were to become a variable you need to put (/ shade) like that. You'll get into (shade)'s later. They can be confusing to discuss when you don't need them. Leave it empty () at this point or put (/ all variable names) like that, as you create variable names.
As far as the hand holding goes, I believe we've all been waiting for this day. I'm sure I'm not the only one that needed some hand holding when I started learning this stuff. However, if I wasn't working out little pieces at a time as I went, I'd have never learned anything.
-
(defun C:mto ();;when i inspect to here i get USUBR@0d01a848 C:MTO> {name} "C:MTO" <flags> {} why???
(setq ename (entsel "\nPick something: "))
;;when i inspected the above line alone i got this for the entity name:7ef377a0
(setq ename (car ename))
(setq elist (entget ename))
(mapcar '-3 (list 0.0 3.0 0.0) cdr (dxf code 72)))
extra credit:
does the mapcar problem have to do with this
(mapcar '-
doesnt there need to be a value there?
the examples i see for mapcar don't appear the same as this to me
-
Why what? Open and closed parens? We'll delve into that another time.
If that's not the question, I'll answer another: Why, USUBR? Because once loaded, your DEfined FUNction (defun) becomes a User-defined SUBRoutine.
Let's get you understanding what different functions do first.
What do you get when you inspect:
(setq ename (car ename))?
What do you get when you inspect;
(setq elist (entget ename))?
As far as the extra credit goes, try this:
(mapcar '- '(10 5 2) '(2 5 10))
Here's what help has to say:
(mapcar function list1... listn)
Arguments
function
A function.
list1... listn
One or more lists. The number of lists must match the number of arguments required by function.
In our sample, is not '- a function?
This is how it should be written:
(mapcar '- (list 0.0 3.0 0.0) (cdr (dxf code from elist here))).
Let's ignore that for now. I put it up there to ease the strain on your mind. We'll get to it soon enough.
-
i am reading through stigs tutorial so i'm sure i'll gain a better understanding as i progress. i've learned alot already. my problem is following the chain of command so to speak because the strucutre keeps changing. i am getting confused on what to analyze first, second, third and so on. i guess that comes with practice (and many hours of banging my head against my desk). here's what i have now but am not sure what to do with the end bits?
(defun C:mto ()
(setq ename (entsel "\nPick something: "))
;;when i inspected the above line alone i got this for the entity name:7ef377a0
(setq ename (car ename))
(setq elist (entget ename));;when i inspect this i see a bunch of info. is this it: [22] (73.0)
(mapcar '- (list 0.0 3.0 0.0) (cdr (dxf code 73.0)))
(subst newlist oldlist elist)
(entmod (above substr))
(entupd ename)
(princ)
-
Let's clean up your code a little. You're doing fine though.
(defun c:mto (/ ename elist)
(setq ename (car (entsel "\nSelect text: "))
elist (entget ename)
)
)
If you were to run this, you'd get a return value; that bunch of info.
[22](73 . 0) is the 23rd item in a LIST containing group code 73 and 0. This is what you've seen called a dxf value or a dotted pair. So far I can tell that your selected text is left justified. What's the value of code 72, 10 and 11?
Extra credit: What other group codes might you find useful from that list and what will 73, 72, 10 and 11 tell me?
-
Oh Dan, I just noticed. When you are looking at the (73 . 0), you're seeing it as a real i.e. 73.0. That's not what it is. What it is is a key-value construct. In other words, the 73 is a key and the 0 is the value. The dot in the middle is the separator and it is separated from the key and the value by a space on either side. Check the cons function. It should help a little. Also, I'm sure in Stig's tutorial, he covers assoc and cons. When you look at the 10 and 11 keys, you'll notice there is no dot separator. It still is a key. The cons function should also make this make sense.
-
i saw what you mean when i was pulling up the info. i did think that was an integer and not a dotted pair. i just got done reading data types :oops: am i in the ballpark here
******************************************************
Group 72 and 73 integer codes
Group 73
Group 72
3 (top)
TLeft
TCenter
TRight
2 (middle)
MLeft
MCenter
MRight
1 (bottom)
BLeft
BCenter
BRight
0 (baseline)
Left
Center
Right
Aligned
Middle
Fit
********************************************************
72
Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
0 = Left; 1= Center; 2 = Right
3 = Aligned (if vertical alignment = 0)
4 = Middle (if vertical alignment = 0)
5 = Fit (if vertical alignment = 0)
See the Group 72 and 73 integer codes table for clarification
*******************************************************
73
Vertical text justification type (optional, default = 0): integer codes (not bit-coded):
0 = Baseline; 1 = Bottom; 2 = Middle; 3 = Top
See the Group 72 and 73 integer codes table for clarification
*****************************************************
10
First alignment point (in OCS)
DXF: X value; APP: 3D point
************************************************************
11
Second alignment point (in OCS) (optional)
DXF: X value; APP: 3D point
This value is meaningful only if the value of a 72 or 73 group is nonzero (if the justification is anything other than baseline/left)
-
Yes, think of it like a matrix. In fact, if you look at the very bottom of that page, you'll see how 3,2 is Top Right. Now, I'm going to go on the premise that your text is 0,0 Left. At this point, all we need to get is the value of 10. Add to the code:
(defun c:mto (/ ename elist)
(setq ename (car (entsel "\nSelect text: "))
elist (entget ename)
code10 (assoc 10 elist)
)
)
To decipher that a little, assoc = associate. What are we associating? Group code 10. What are we associating it to? The entity list that this particular 10 is in. In code: (assoc 10 elist). When you inspect that piece, you'll end up with four sets of numbers and 10 will be the first one. The code above is a fully functioning program. In autocad, after running mto, type !code10. What's returned? Type !elist or !ename. You should get nil as the return on the last two. Why? and why is that not the case with code 10?
I'm going home now. Your homework assignment is this: study assoc, cons, and list. Also, find the functions that will strip the key (10) out of the list we've just assoc'd and play with them a little.
-
ok daron i plan to print this out and view it at home when i can focus better, there's insanity going on all around me. thanks for all of your help
-
i'd like to study the topics you say but i'm thinking it would probably be a good idea to read stigs tutorial in the order it was presented. i think i should be trying more of his exercises as i'm going along so the concepts stick. i actually think i might refresh on lessons 1 and 2 because i read those awhile ago and haven't retained everything :oops: so that's what i'll be doing today
-
Dan, I'd stick with this and use his tutorials as a reference. Hold on. Two things: 1) It hasn't stuck because it hasn't been applied. 2) Lesson 1 and 2 are both good, but hold on to reading lesson 2 for now. We'll get into that as we build this if you stay with me. I'm walking you through this. Let's get you understanding what to use for the purposes you desire, then lesson 2 will make more sense than ever before. Lesson 1 is a fine primer. If you want to read any tutorial, go to lesson3 and focus in on the 10th page. These are the functions I need you to understand for the point we're at with your program we're building here.
Don't bail out on me, Dan. Sure Stig's turorial's are great, but if you never put them down to real application no amount of greatness will ever be retained. Take whatever time you need to do your daily work, but keep this thread going. You will start to understand.
When I was learning, I had someone right there to walk me through it. It took me months to get many concepts down and I was always asking him questions about how to automate this or that. He put a lot into teaching me. You have it better. You have many people who'd bend over backwards to help you build your knowledge in this area. Take hold of it. Don't let this procedure die. Stay with me.
-
i'm with you daron it's just that my boss really wants me to work on the tools for text masking . i have four lisps:1 that will mask selected text (which is working) 2 which will mask all text (which is not working) 3 which will unmask selected text (which is not working) and 4 which will unmask all text (which is working). basically all i did was include an an ssget and an ssget "x" in both then comment out one or the other but it's not working. here's all four so once i can get that out of the way i can get back to our discussion:
this is working*************************
(defun C:TMS (/ MASK_LIST ENT SS)
;;(command "_.texttofront" "T")
;;(setq SS (ssget "x" '((0 . "mtext"))))
(setq ss (ssget))
(setq MASK_LIST
(list
(cons 90 3)
(cons 63 256)
(cons 45 1.5)
(cons 441 1616860)
)
N 0
)
(if SS
(repeat (sslength SS)
(setq ENT (entget (ssname SS N)))
(setq ENT (append ENT MASK_LIST))
(entmod ENT)
(setq N (1+ N))
)
)
(command "_.texttofront" "T")
(princ)
)
below is not working*********** it returns nil???
(defun C:TMA (/ MASK_LIST ENT SS)
;;(command "_.texttofront" "T")
(setq SS (ssget "x" '((0 . "mtext"))))
;;(setq ss (ssget))
(setq MASK_LIST
(list
(cons 90 3)
(cons 63 256)
(cons 45 1.5)
(cons 441 1616860)
)
N 0
)
(if SS
(repeat (sslength SS)
(setq ENT (entget (ssname SS N)))
(setq ENT (append ENT MASK_LIST))
(entmod ENT)
(setq N (1+ N))
)
)
(command "_.texttofront" "T")
(princ)
)
this is not working************************ it returns ; error: extra right paren on input?????????
(defun C:UTMS (/ SS N)
(vl-load-com)
;;(setq SS (ssget "x" '((0 . "mtext")))
(setq ss (ssget))
N 0
)
(if SS
(repeat (sslength SS)
(vla-put-backgroundfill
(vlax-ename->vla-object (ssname SS N))
0
)
(setq N (1+ N))
)
)
(princ)
)
this is working*****************************
(defun C:UTMA (/ SS N)
(vl-load-com)
(setq SS (ssget "x" '((0 . "mtext")))
;;(setq ss (ssget))
N 0
)
(if SS
(repeat (sslength SS)
(vla-put-backgroundfill
(vlax-ename->vla-object (ssname SS N))
0
)
(setq N (1+ N))
)
)
(princ)
)
-
i actually just finished lesson 3 so that is pretty fresh
-
error: extra right paren on input?????????
I don't know if this will make it work, but they always say, programming is 95% debugging, or something like that. I'll point you for where to look, but I'm not going to show you what the problem is. First take the error message to heart and remember that in lisp, for every open paren you need to close it. Here's the area to look at:
(setq ss (ssget)) N 0)
Hint: is the setq closed? If so, what function would N be performing? IOW, there's a right paren you need to get rid of.
-
nevermind i got it. the first one was that i didn't put a space after i loaded it in my button. the second was the extra paren after ssget proceed... 8)
-
Now that you got that all figured out, where do we stand in our app? I'll repost it.
(defun c:mto (/ ename elist)
(setq ename (car (entsel "\nSelect text: "))
elist (entget ename)
code10 (assoc 10 elist)
)
)
So far, we have a USUBR that return a group code list. After running mto you're returned:
(10 x-coord y-coord z-coord)
Type in autocad !ename, !elist and !code10.
Why do the first two return nil (and they should) and the last one return the list or return value. This should be covered in lesson2 I believe.
On to the next portion, how can you lose the 10 in the returned list? IOW, what function "Returns a list containing all but the first element of the specified list"?
-
ummm cdr heeeeeey i didn't even peak 8)
-
mine has another paren at the end. yours returns malformed list here's mine:
(defun c:mto (/ ename elist)
(setq ename (car (entsel "\nSelect text: "))
elist (entget ename)
code10 (assoc 10 elist)
)
)
-
ididn't get the last result when i ran that line i got nil as well but i'm guessing it's because they have no values attached to them??
-
could you use newlist in combonation with cdr to narrow it down?
-
Hehe. I must've not copied that last paren.
So, did you try the other items?
Let's move on then.
Where are you going to put the cdr in your routine above? I don't feel that you need to create another variable for it and cdr requires a list, so set it and post it and then we'll move on, but you need to answer the first question before I do.
-
(defun c:mto (/ ename elist)
(setq ename (car (entsel "\nSelect text: ")) ;;we get the list
elist (cdr (entget ename) ;;we have the list and want to get the dxf code we need from the list
code10 (assoc 10 elist) ;;we get the dwf code ename
;;i am guessing the cdr goes in the third line???
)
)
-
i'd like to comment everything so i know what's going on which i'm not sure that i do?
-
could you use newlist in combonation with cdr to narrow it down?
Yes, you could as you've done in your code above, but it would amount to very little. Remember me telling you about keys and values? With (assoc 10 elist) we've grabbed the list we want to manipulate. All we're trying to do now is remove the 10 from the associated list and pass it to the variable code10.
Oh, let me let you in on something: When viewing an elist, you are looking at a list containing a bunch of other lists of an entity. We don't need to manipulate the elist itself but a list within it. CDR the next line down, just the way you've placed it now and the routine will return the group 10 list without the 10 in it.
Is this all starting to make sense?
Have you tried my question from previous posts about typing in acad !ename, !elist and code10?
-
Command: !ename
nil
Command: !elist
nil
Command: !code10
(10 1077.0 811.598 0.0)
(defun c:mto (/ ename elist)
(setq ename (car (entsel "\nSelect text: ")) ;;we get the elist
elist (entget ename) ;;we have the elist and want to get the ename we need from the list
code10 (assoc 10 cdr elist) ;;we get the ename and break it down
;;is this placement right. when i inspect it it say complete the expression???
)
)
-
i've put the cdr in various places in that line and cannot get it to return without the 10 :cry:
-
(cdr (entget ename)
Just like you did here, Dan. Wrap () the (assoc 10 elist) in the cdr like: (cdr (assoc 10 elist)).
Command: !ename
nil
Command: !elist
nil
Command: !code10
(10 1077.0 811.598 0.0)
Now answer this question, why are the first two nil and the third one has a value? Read Lesson2 at around page 8 for help. Ask, if that still doesn't help.
-
sigh i don't know i see that page talks about using arguments and variables in defun. are these 2 variables and the last a value?
-
Local and Global variables. I don't want to define the difference here. It's been covered to exhaustion on this forum. I will tell you this and then we can move on. !ename and !elist are defined as local variables currently and !code10 is defined as a global variable. There is no need for it to be Global.
Question: What can we do to make it Local?
Hint: Look at the line that defun is on.
Post the code with the cdr and code10 localized and we'll move on.
Don't worry if it seems overwhelming. Some of these things I'm pointing out so when we need to worry about them, the light will turn on.
-
daron i was telling my boss about stigs class and told her i was trying to write something. she said why dont i ask her and jumped into the creation of this lisp, renaming some variables and performing some tests so i understand what's going on. i think i know what you mean about localizing the variable code10. i needed to add it after elist at the beginning. my boss thought i should name the variables so they make better sense and declare them once i finish. anyway here is the testing she had me do and my code in the current state:
Command: (setq txtname (car (entsel)))
Select object: <Entity name: 7ef977a0>
Command: (setq txtlist (entget txtname))
((-1 . <Entity name: 7ef977a0>) (0 . "TEXT") (330 . <Entity name: 7ef94cd0>) (5
. "2A7C") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 2) (100
. "AcDbText") (10 1077.0 811.598 0.0) (40 . 3.0) (1 . "S.C.") (50 . 0.0) (41 .
1.0) (51 . 0.0) (7 . "ROMANS") (71 . 0) (72 . 4) (11 1081.29 813.098 0.0) (210
0.0 0.0 1.0) (100 . "AcDbText") (73 . 0))
Command: (setq pt1temp (assoc 10 txtlist))
(10 1077.0 811.598 0.0)
Command: (setq pt1 (cdr pt1temp))
(1077.0 811.598 0.0)
(defun c:mto ( / )
(setq txtname (car (entsel "\nSelect text: ")) ;;we get the txtlist
txtlist (entget txtname) ;;we have the txtlist and want to get the txtname we need from the list
pt1 (cdr (assoc 10 txtlist));;we break this down to only the coordinates
)
)
-
now that i have the coordinates of the text i want to move stored how do i get the midpoint of the dimension line. i thought i could do it the same way but i'm not sure about the format or the dxf code for the dimension line?
(defun c:mto ( / )
(setq txtname (car (entsel "\nSelect text: ")) ;;we save the txtname
txtlist (entget txtname) ;;we have the txtlist and want to get the txtname we need from the list
pt1 (cdr (assoc 10 txtlist));;we break this down to only the coordinates
(setq dimname (car (entsel "\nSelect text: ")) ;;we get the dimlist
dimlist (entget dimname) ;;we have the dimlist and want to get the txtname we need from the list
pt2 (cdr (assoc 1 dimlist))
)
)
-
(defun c:mto ( / )
I hesitate to get into this.
What you have there is fine, though unneccesary. (defun c:mto () will also work, however, what you've done is globalized ALL your variables. You want to Localize them or one day you'll end up with a slow processing computer. To localize them we need to ADD
(defun c:mto (/ txtname txtlist pt1)
This will clear all your variables to nil when you are done processing the lisp. I have to work with an add-on right now that has all kinds of global dependencies. It sucks and if any of them gets changed, the whole program (add-on) won't work properly until I restart autocad.
As far as changing the variable names to make more sense, I agree, but what happens when we go from selecting single text objects to multiple text objects? Honestly, it doesn't matter, since the end user will never know the difference. As long as you, the code hacker can understand it when you go in to edit it 3 months down the line, is all that matters. What you wouldn't want to do is something like:
(defun c:mto () ;<-Naming like this isn't good either.
(setq a (car (entsel "\nSelect text: ")
b (entget a)
c (cdr (assoc 10 b))
)
)
After a while the code gets a little long and you'll tend to forget what "a" means.
Let's get back on topic. Localize your variables (/ txtname txtlist pt1).
All you need is the return value. Post your code and I'll see what's next.
-
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
Add this to the top of the code, so we remember what it is we're trying to accomplish. This is your pseudo-code. It'll help us retain focus. I just looked at it again and realized that we need to select the dimension line. Why don't you take that as your next assignment within the current function. Add the selection of a dimension and go about getting an elist of it. We'll need that.
Every time you post code make sure that the pseudo-code is also attached.
-
Just to dovetail (by example) onto what Daron is saying consider this ---
(defun c:example ( / ename data result )
(if (setq ename (car (entsel)))
(cond
( (eq "TEXT"
(cdr
(assoc 0
(setq data
(entget ename)
)
)
)
)
(setq result
(cdr
(assoc 10 data)
)
)
)
)
)
result
)
Salient points: (1) Somewhat error trapped (traps an unsuccessful entity selection), (2) variables are self describing, (3) variables are declared as locals, (4) coded to work [at this time] specifically with text objects, (5) the overall structure is flexible, lending itself to future growth.
-
something like this. i was trying to figure out how to get pt2. i thought it would be the same idea but i am not sure how to join the 2 parts or if the dxf code is right. maybe i'm wrong but i'm playing around with it:
c:mto (/txtname pt1 dimname pt2)
(setq txtname (car (entsel "\nSelect text: ")) ;;we save the txtname
txtlist (entget txtname) ;;we have the txtlist and want to get the txtname we need from the list
pt1 (cdr (assoc 10 txtlist));;we break this down to only the coordinates
(setq dimname (car (entsel "\nSelect text: ")) ;;we get the dimname
dimlist (entget dimname) ;;we have the dimname and want to get the dimname we need from the list
pt2 (cdr (assoc 1 dimlist))
)
-
thanks for not laughing yet by the way :oops:
-
i am testing the dimension text the same way i looked at the plain text and come up with this.
Command: (entsel "\nSelect text: ")
Select text: (<Entity name: 7ef97738> (1083.3 820.807 0.0))
can you look at my comments and help me because i don't think that's what's happening
-
MP, we'll get there. I was leaving error trapping out as that can be more confusing than me to a beginner. Please continue to add your comments, though. I certainly don't want to squander any growth or understanding that Dan can get from others.
Try to set up the exercise I've given >here< (http://www.theswamp.org/phpBB2/viewtopic.php?p=74037#74037) to getting dimension elist. If you want, you can create a whole new USUBR for it and maybe we'll get into calling external routines and the importance of return values.
-
ok i'm getting spun around and don't know what's going on. mp i can kinda see what you're getting at and i do appreciate the advice. daron the link you posted is to this page where i don't see the exercise you're talking about. did you see what i tried. not sure where to go?
-
I didn't see your post Dan. I was trying to point to this page so my post wouldn't get lost in the shuffle. It appears that you did try to get the dimension object. Here's the issues I have:
1) you've got a setq that doesn't need to be there or you need to close out the first one before starting a new one.
2) I know your initial intention is:
move the text to the midpoint of the dimension line
then move the text down 3-1/2
but we're not going to do this any conventional way. What we're going to do is get points and substitute the point list we come up with in the dimension for the current point list of the text. I know this doesn't make much sense, but as we go you'll get the picture.
I should probably let you find the bugs, but I'm going to post what we have to date and add what you were trying to do with some extra items to think about.
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MoveTextToDimension (/ txtentity txtlist
txtassoc10 dimentity dimlist
dimassoc10 dimassoc11 dimassoc13
dimassoc14 dimassoc42
)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
txtassoc10 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
dimassoc10 (cdr (assoc 10 dimlist))
dimassoc11 (cdr (assoc 11 dimlist))
dimassoc13 (cdr (assoc 13 dimlist))
dimassoc14 (cdr (assoc 14 dimlist))
dimassoc42 (cdr (assoc 42 dimlist))
)
)
I changed some of the variable names. On the new portion test each dimassoc value. Look for their meanings in the dxf reference area under common dimension group code under Dimension under Entities. Some we'll use, some we won't. This may be a difficult task, but can you find which one's we won't need? One way to see what each point does minus 42 is inspect that setq block making that block global. Then, in autocad draw lines. When it asks for points as the line command does, supply !dimassoc10, !dimassoc11, etc. 42 is not a point value, so this one won't work. I put it in there because we're definately going to need it. What we won't need are two of the others. Study it a bit and tell me what you think.
I changed the name too. If you want to set it back to three letters, do this:
(defun c:mto () (c:MoveTextToDimension) (princ))
-
;;pick the text using the node as the point
Just had a thought. Maybe this'll pique some light. The user currently can select a piece of text and we've supplied a point value. This point value is not the node as you'd normally use it, though it is most likely the same point you'd normally pick. One thing we're not going to do here is use any osnaps. Don't worry, we're still going to get the precision that osnaps give you. Also, when we're done here, your code will not have command in it, except maybe (command ".undo" "be") and (command ".undo" "e"), if we choose to use that. There're some fun exercises in there too if we don't.
-
MP, we'll get there. I was leaving error trapping out as that can be more confusing than me to a beginner.
Sorry, I shouldn't haved butted in, but I couldn't help myself. The pace you're conducting is fine Daron. Kudos to you for taking the initiative to help out Dan like this.
-
Thanks. Don't worry about butting in. I may need help teaching and someone like yourself can bring it to a level I may not be able. Plus, sometimes I tend to add too much information, thus overwhelming the person I'm trying to teach. I'm trying very hard to keep it toned down for Dan and I'm glad he came up with something that he needs that doesn't have to be TALL order, even though it could certainly become tall order when we get into "user friendliness" and portability. I don't mean portability like from one OS to another, just from one users idea of how it should work and anothers. Finding all the ways a dimension needs to be handled will certainly add to the height of the order, but it will also lead Dan down the road to understanding a great deal more than he thought possible.
Dan, don't feel overwhelmed here if you're not remembering things. I know I didn't get it after one or two lisps. I'd ask questions of the same things. When I started writing function repetedly, is when I started understanding how they work. You'll use things like entsel, cdr, car, entget and assoc so regular that eventually you'll know exactly what it is you need and you'll wonder how you ever didn't know.
-
daron i see that 10 is the endpoint of the dimension line, 11 is the midpoint of the text, and 13 and 14 are the left and right origin points of the dimension. i think we need 11 but not sure what else, you said we need 2? i see what you mean about not needed osnaps or commands we can just grab and place the entity where we want with the code so we dont need a conventional move command persay.
-
ah missed the new posts. i'm so glad i have this place to learn. i'm picking things up little by little and like you say eventually i'll just be able to hop on the bike and off i go. the good thing is i am aware of the possibilities from seeing the stuff coded here and i'm excited about the future and proud of myself for making the leap into learning how to do for myself.
-
Yeee-Hawww.
;;then move the text to the midpoint of the dimension line
We're not going to move the text to the midpoint of the DIMENSION line, but we are going to get that point. This is the point we're about to get.
Okay Dan. I'm going to spell it out for you now. I see that you tried and since you can't look into my mind to see where I'm going to go with this this'll take a load off. Okay, let's see; when I was testing this, I was looking into finding the midpoint of the dimline by using 10 and 11. 11 isn't the middle of the dimension line as I understand it, but the middle of the dimension text. So, if the text is not in the middle of the dimension line, you're going to have trouble. Now, if you move your dimensions and you want the text we're moving below the dimtext, then we're going to have to go the GC11 route, but for now, I'd like to assume you're not concerned with that and we're going to go a slightly different direction, which will give you knowledge of some more functions that as you begin to understand, you'll want to use commonly. Also, I found some quirky things happening when trying to subtract some values from pt10 and pt11. So, to avoid the conflict I had, we're going to alter the course and make sure we get the points we need which by your criteria, is the middle of the dimension line.
Okay, I said I'd spell it out for you, so here it is. We do need GC10, but let's look at GC14. GC14 is origin point along the same line as 10, so you have a common line to all dimensions here. I just stumbled across a little issue. I went back and tested something and it appears we'll need GC13 as well, but let's not worry about that right now. I'll explain later. Right now, I want you to look at a couple of help topics: angle and polar. Read up on these and see if you can make sense of them. I can't find polar in any of Stig's lesson's. If you can great, otherwise just try and tell us what you find concerning polar and angle and we can move ahead.
and proud of myself for making the leap into learning how to do for myself.
I'm sure many of us are too. As well, when you do have a more sound understanding, you'll be able to pitch in with some help to others, which is the greatest benefit.
-
Suggestion: After the dxf coding techniques are explored parallel functionality using activex techniques should be discussed.
-
You don't think it's too early? I was thinking get him on solid ground first. I'll see what I can do with AX.
-
let's just say i could use 11 because i highly doubt this dimension text will bee moved from it's default. i know you are trying to error trap but on the other hand do we really need to complicate it that much. i'm willing to learn the error free way it was just a thought. not sure why we need 10, 13, and 14 but i'll trust ya you're the teacher. :lol: ok i'm not sure where in help you want me to look for angle and polar and what aspects of angle/polar should i be looking at?
-
Suggestion: After the dxf coding techniques are explored parallel functionality using activex techniques should be discussed.
:)
-
whatever you think is the right way but i must warn you it doesn't take much to ovewhelm me at this stage so k.i.s.s. definitely applies here :?
-
We've been there Dan; I'm no rocket surgeon.
:lol:
-
so... what should i look at?
-
Stay with the dxf stuff Daron is laying out for you for now. Once you get to the "aha" stage then we'll show you how to do the same thing using activex.
-
yeah but he said to look into angle and polar but i'm not sure what he means. look where?
-
Ya gotta learn to use the help available, that's an absolute must.
Returns an angle in radians of a line defined by two endpoints
(angle pt1 pt2)
Arguments
pt1 - An endpoint.
pt2 - An endpoint.
Return Values
An angle, in radians.
The angle is measured from the X axis of the current construction plane, in radians, with angles increasing in the counterclockwise direction. If 3D points are supplied, they are projected onto the current construction plane.
Returns the UCS 3D point at a specified angle and distance from a point
(polar pt ang dist)
Arguments
pt - A 2D or 3D point.
ang - An angle expressed in radians relative to the world X axis. Angles increase in the counterclockwise direction, independent of the current construction plane.
dist - Distance from the specified pt.
Return Values
A 2D or 3D point, depending on the type of point specified by pt.
-
In help under AutoLisp Reference. "A" for angle and "P" for polar. You'll find a whole new world in that reference.
-
Thanks MP. Dan, I want you to find what MP posted for you. If you can find the dxf info, I'm sure you can find the ALisp References. Now, explain angle. What is its return value? What will that return value do for you? Can it be used in polar? If so, does it need to be converted to human readable degrees for polar?
-
not sure why we need 10, 13, and 14 but i'll trust ya
10 and 14? Here's an exercise: In acad, run rotate. Select a dimension and on a node (where you think code14 might be) spin that baby around kinda not too fast. Notice how the angle of the whole dim object is constantly changing.
You will undoubtedly have dimensions at different angles, even if they are only ever horizontal and vertical. Regardless, using GC10 and GC14 we will always have a dimension defined angle to go from. The reason we'll need GC13 is because we need to know which direction we're going to have to get our midpoint from: 0, 90, 180 or 270 from the angle of GC10 and GC14. If you don't use GC13, your text could end up the distance of the dimtext and GC10, the opposite direction.
-
aha ok now that you mention it it would be nice to be able to move the vertical text as well if i have to stretch the height. so the angle tells the angle between 2 endpoints. the polar species the point to which we want to move our text based on the angle and point we already have aquired. am i close here?
-
Not sure what you mean by "species". I'll assume a typo, but I can't figure out what word should be there. Angle does tell the distance between two POINTS. Let's leave the word ENDpoints out of it though, since angle can give you the angle between any two given coordinates. They don't have to even be attached to an object and literally, the coordinates we're playing with here aren't attached to the object. In fact, coordinates are never attached to an object, though an object might be attached to a coordinate. Even when using reactors, you're still adjusting to coordinates.
As far as polar goes, you are close, but I know too well that polar can be more complicated than you realize. What polar is going to do is take a starting point an angle and a distance and return a coordinate from the supplied point, the distance supplied by the angle supplied. If we plug in (polar code10 (angle code10 code14) 5000.0) we'll get a coordinate point 5000 units along coordinates code10 and code14. That's not what we're looking for is it? Are you familiar mathematically with how to get an angle like 90 degrees?
-
a typo yes i meant that to be specifies but got ahead of myself :oops: i think i follow you about polar but the last question i don't entirely understand, no?
-
i am listening to lynn allens live meeting of getting the most out of 2006 as we are discussing this so bear with me
-
Maybe this will help, maybe not.
One radian is the angle of an arc created by wrapping the radius of a circle around its circumference.
The radius 'r' fits around the circumference of a circle exactly 2p times. That is why the circumference of a circle is given by:
circumference = 2(pi)r
So, how are we going to find 90 degrees from (angle code10 code14) toward code13?
This is what we should have at this point.
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MoveTextObject (/ txtentity txtlist
txtassoc10 dimentity dimlist
dimassoc10 dimassoc11 dimassoc13
dimassoc14 dimassoc42
)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
txtassoc10 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
dimassoc10 (cdr (assoc 10 dimlist))
dimassoc11 (cdr (assoc 11 dimlist))
dimassoc13 (cdr (assoc 13 dimlist))
dimassoc14 (cdr (assoc 14 dimlist))
dimassoc42 (cdr (assoc 42 dimlist))
)
(setq dimang (angle dimassoc10 dimassoc14))
(setq dimlen (/ dimassoc42 2.0))
)
I've added the angle to it and threw in a little something extra. You'll see that last piece there. Can you guess at its purpose? Hint: What is group code 42?
-
I'm sure that's more entertaining. She's a fun speaker.
-
sorry bout that daron i was listening to lynn then went out for lunch. let's see, that last part is to move the text 2. 'ill read through the code some more
-
daron i know what you are trying to do being that you are an experienced programmer. you are trying to write the programmer for all situations. the problem on my end is that my boss keeps checking in on me and asking me how it's going. i told her that we are doing some further development of the routine. she says while that is a good thought she wants me to keep it simple so i can easily interpret what is going on. then as i progress the routine can be further developed. she wants me to just write a routine that does what i described in my psuedo code only for horizontal dimensions then be able to know exactly what is happening. in other words can we just extract the code11 from the dimension then place the text 3.5 below that point. sorry but she is about to give me a drawing to do so i will have to take a break from writing anything after today. i will continue to read and come up with a list of questions as i go.
-
Not to move the text any, yet. I think you might be on to something though. Consider what code42 is and what (/ dimassoc42 2.0) means. It's just math. Consider that this (/ dimassoc10 2.0) won't work and explain why. You'll find / under Operators in the Alisp Reference. You'll also slap yourself if you didn't realize that it is telling the computer to divide one element from the other. Don't confuse it with (defun (/ errata) in the first line of this routine. They aren't the same. Confusing enough? Well, I'm going home. Until tomorrow.
If you need any extra work, look up subst (substitute), entmod (ENTity MODify), entupd (ENTity UPDate) and cons (CONStruct). Fun fun. Oh, explain all your findings of each. This way I know where you stand.
-
daron i was trying to code it so it could just work for horizontal dimensions and here's what i came up with so far. i'm not sure how i tell it to move the object from pt1 to newtxtpt? what do you think?
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MTOO (/ txtentity txtlist
pt1 dimentity dimlist pt2
txtxcoord txtycoord newtxtpt
)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
pt1 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
pt2 (cdr (assoc 11 dimlist)))
)
(setq txtycoord (cadr (assoc 10 txtlist))
)
(setq txtxcoord (car (assoc 11 dimlist))
)
(setq newtxtpt (list txtycoord txtxcoord 0)
)
(command "move" pt1 newtxtpt)
-
I've been waiting for you to come in and while what you've done shows that you're progressing well, your program here is built with a closing parenthesis in the wrong place. It will load, but everything past setq pt2 won't be part of the program as these have become four separate entities. Now, I'm sure the reason you want to jump ahead here and just work for horizontal dimensions is because you want something that works, so you can keep working at work, while continuing to learn and develop a more complete piece of code. So, fix your code above and localize your variables, meaning add variable names to (/ ) <-that area in the defun line. No globals.
I'm not done with you in the direction I want to take you. I see that you understand how to use (command etc...). I'm glad. That means I don't have to teach that. What it does mean is I need to teach you when you don't need to use it. In this training session we're not going to use it unless absolutely necessary. Let's continue. Did you look up subst (substitute), entmod (ENTity MODify), entupd (ENTity UPDate) and cons (CONStruct). This is where we stand.
I did a lot of thinking last night on how to know whether we need to send polar in a negative angle or a positive angle and it's pretty simple, really. Once we get a general direction, we'll get into if, cond and predicate functions.
-
OBTW, we are almost done with a quick and dirty working function. There's only a few things left. When we get you something working, really, then we'll get into making sure anybody who gets ahold of it won't come back to you asking why it stopped working when they missed the objects, or that they picked a line instead of a dimesnsion object and it didn't work. At this point, there are many bugs, even though it will work.
-
Dan, just a thought. When trying to find misplaced parentheses, start from the inner most nested set of each line and work outward. When you see one that looks like it's in the wrong place it most likely is.
-
Dan, I've got some more reading for you to do. Pick the link in here. (http://theswamp.org/phpBB2/viewtopic.php?t=137) This should help you navigate the vlide.
-
daron i suspected something was wrong but have not been able to figure out how to piece things together. how do i go from line ****** to line________. i havent gotten the parens completely down yet. as i said i have to jump into a job soon so i won't be able to dedicate myself full time to learning for awhile (at least not at work). i hate to bail out on ya but am afraid i must soon.
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MTOO (/ txtentity txtlist
pt1 dimentity dimlist pt2
txtxcoord txtycoord pt3
)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
pt1 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
pt2 (cdr (assoc 11 dimlist))*************************
)
(setq txtycoord (cadr (assoc 10 txtlist))_________________
)
(setq txtxcoord (car (assoc 11 dimlist))
)
(setq pt3 (list txtycoord txtxcoord 0)
)
(command "move" pt1 pt3)
-
Let's see if this'll help you out. Look for openings and closings:
(defun c:MTOO (/ txtentity txtlist
pt1 dimentity dimlist pt2
txtxcoord txtycoord pt3
)
(setq txtentity (car (entsel "\nSelect text: ")))
(setq txtlist (entget txtentity))
(setq pt1 (cdr (assoc 10 txtlist)))
(setq dimentity (car (entsel "\nSelect dimension: ")))
(setq dimlist (entget dimentity))
(setq pt2 (cdr (assoc 11 dimlist))
)
(setq txtycoord (cadr (assoc 10 txtlist)))
(setq txtxcoord (car (assoc 11 dimlist)))
(setq pt3 (list txtycoord txtxcoord 0))
(command "move" pt1 pt3)
I cleaned up the code a little. Every line, except defun has its opening and closing parenthesis on that line. The code is all indented for easy reading and the misplaced closing parenthesis is also set to show which piece of code it belongs to. You'll see that it's still in the wrong place. Defun (DEfine FUNction) is the least nested piece of code. What I mean by that is all parentheses needed to be in the function need to be contained (nested) within the defun's opening and closing parenthesis. Does that make sense? If you can, print ofs all the information I've asked you to study and over the weekend study it a bit. Post any comments of questions or new understanding you have when you can.
-
daron when i load this it loads fine. i pick the text then the text then the dimension and it gives me this error message and i'm not sure what is wrong with this line that is causing it. it is this line, right?
(setq pt3 (list txtxcoord txtycoord 0)
)
(defun c:MTOO (/ txtentity txtlist pt1 dimentity
dimlist pt2 txtxcoord txtycoord pt3
)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
pt1 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
pt2 (cdr (assoc 11 dimlist))
)
(setq txtycoord (cadr (assoc 10 pt1))
)
(setq txtxcoord (car (assoc 11 pt2))
)
(setq pt3 (list txtxcoord txtycoord 0)
)
(command "move" pt1 " " pt1 pt3)
)
-
whoops :oops:
-
my error message:
Select dimension: ; error: bad association list: (954.876 1028.99 0.0)
-
(setq pt3 (list txtxcoord txtycoord 0))
What I'm seeing here is that your association list is asking for a real number and you've supplied an integer. Try changing it and see what you get. On the other hand, if you have some time, when you're done looking through the assignments I've asked you to look into, minus the vlide editor tutorial, the one we've been working on will also be in working order and it will work on dimensions set at any angle.
The math I worked out yesterday, kept me up. I didn't get much sleep because my mind was still focusing on angular calcs and how we can make this work, while I was trying to sleep. So, because I'm sleep deprived, you owe it to me to find some time to keep this going (keeping your work schedule in check though. I wouldn't want you to get lectured because of me). I'm anxious to give you the code, but I want you to understand it before I do. In fact, it'd be great if you could stumble upon the answers I've got yourself, but I want to guide you. You're doing well. Keep it up and don't let too much time slip by.
-
daron i got it to work sorta. it moves the text but the text is actually left justified not center so it places the text off center to the right. also i noticed that depending on the zoom it places the text in a different location. the first part of the question concerns assoc 72 right but once i extract the info i need how do i group that with the 10 coordinates and carry that info to the end of the routine. a list i suppose. i'll play around with it over the weekend and read the topics you suggested. thanks a bunch for your help i know it's not easy slowing to a crawl.
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MTOO (/ txtentity txtlist pt1 dimentity
dimlist pt2 txtxcoord txtycoord pt3
)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
pt1 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
pt2 (cdr (assoc 11 dimlist))
)
(setq txtxcoord (car pt2)
)
(setq txtycoord (cadr pt1)
)
(setq pt3 (list txtxcoord txtycoord 0)
)
(command "move" pt1 "" pt1 pt3)
-
I was wondering when we'd hit that roadblock. For the time being, there's an express tool called justify text you might use before issuing your code. When you get more time, we can then tackle moving the text from the middle of the length x half the height of the text to the point you want.
-
daron i discovered that it not putting the second text in the right position had something to do with osnap being on so i turned it off then back on and it works for now. we'll improve upon this when i get another free moment but i must get back to work now. thanks you for all of your help you're a saint :wink:
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MTO ( / txtentity txtlist dimentity dimlist txtxcoord txtycoord pt1 pt2 pt3)
(setvar "osmode" 0)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
pt1 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
pt2 (cdr (assoc 11 dimlist))
)
(setq txtxcoord (car pt2)
)
(setq txtycoord (cadr pt1)
)
(setq pt3 (list txtxcoord txtycoord 0)
)
(command "move" pt1 "" pt1 pt3)
(setvar "osmode" 127)
(princ)
)
-
:lol:
As for the code, try this:
;;pick the text using the node as the point
;;then move the text to the midpoint of the dimension line
;;then move the text down 3-1/2
(defun c:MTO ( / txtentity txtlist dimentity dimlist txtxcoord txtycoord pt1 pt2 pt3)
(setq osm (getvar 'osmode))
(setvar "osmode" 0)
(setq txtentity (car (entsel "\nSelect text: "))
txtlist (entget txtentity)
pt1 (cdr (assoc 10 txtlist))
)
(setq dimentity (car (entsel "\nSelect dimension: "))
dimlist (entget dimentity)
pt2 (cdr (assoc 11 dimlist))
)
(setq txtxcoord (car pt2)
)
(setq txtycoord (cadr pt1)
)
(setq pt3 (list txtxcoord txtycoord 0)
)
(command "move" pt1 "" pt1 pt3)
(setvar 'osmode osm)
(princ)
)
That was something I was aware of. I wanted you to find it and you did. Good call. Now, if you want to set it to what was previously set, it will be, even if it was 127 to begin with.