Sittingbull Posted December 15, 2010 Posted December 15, 2010 Hello all, Beeing a total noob with lisp, i try to learn from several post here and there. I have like 1300 matlist files i'ld like to edit. The drawings are simple. They include some text, attributes and lines. looks like this: ------------------------------------------------------------------ | Pos | Qty | Ref | Description(4x) ------------------------------------------------------------------ The pos,qty and ref are text objets. The descriptions are attributes. There are 4 of them(different languages). All text objects and lines are in the same layer. That's my problem. The attributes are in different ones for each language like it should. What i would like to do is select only the text objects to put them in another layer(laymrg). Ones this is done i could proces all the files to change the layers with lisp programs i went ninja ono:)(thx CADkitt, Lee and David). This would have to be done without my input(without selecting anything), as i'ld include the code into the routines i already have to batch proces all the files. I could parse the code i have to create and change layers in this post, and have it modified by some of you geniuses, to act only on text objects. But i don't think it's gonna help me understanding what i'm doing. A better id, i think, is to execute the codes one by one at the command promt and get a better understanding of what they do. Here are the steps i'ld like to go though: 1. select only the text objects. 2. execute a command like laymrg I read about "entget" "ssget" "mapcar" and "lambda". But i'm just not there yet to have it all work together. Here is what i have so far to select only text objects: (entget (0."text") or (setq myText (list (cons 0 "text"))) I think this last one puts all the text objects in the variable myText? This is where i get stuck. I can't manage to have the laymrg command working after that:oops:. i tried this: (command "laymrg" (car myText)) But i know i'm so far from the real thing. I'm reading as much as i can and am looking forward to a formation in lisp. Meanwhile i'm taking my chances in this forum:wink:. SB Quote
BIGAL Posted December 16, 2010 Posted December 16, 2010 something like (prompt "\nSelected text objects to change layer ") (setq s1 (ssget "X" '(( 0 . "text")) )) (command "chprop" s1 "" "layer" "newlayername" "") (princ) ) Quote
Sittingbull Posted December 16, 2010 Author Posted December 16, 2010 Yes it helps, thx a lot. I guess i have to read a bit more about simple codes. I'll be back laters Quote
Sittingbull Posted December 19, 2010 Author Posted December 19, 2010 Hi all, I've done my homework ^^. Here is what i found for simply selecting text objects: (setq mytxt (ssget '((0 . "*TEXT")))) I understand it assigns a selection set of all text objects to the mytext variable. The " ' " character (quote?) prevents the list (0."*text") from beeing evaluated, isn't it? But i don't realy understand why. I suppose 0."*text" is between double brackets because one pair is from the list and the other two are bound the way autocad considers entities? Is the " * " character used so all type of text is included?( single and mtext?) Finaly, how can i get this selection set to my variable, without selecting the objects myself? I tried with entsel and entget, but get only errors. Back to this fine ABC's website:wink:. Laters. Quote
Lee Mac Posted December 19, 2010 Posted December 19, 2010 You could select all Text/MText/RText objects using: (ssget "_X" '((0 . "*TEXT"))) ssget filter lists allow the use of wildcard strings, hence we can use the asterisk ( * ) to match any entities with an entity type ending in the string TEXT. To avoid the selection of RText, we could use this filter: (ssget "_X" '((0 . "TEXT,MTEXT"))) This uses the comma ( , ) to separate the two patterns. To learn more about using wildcards to match strings, research the wcmatch function in the VLIDE - not sure how to do that? See here (and here if you haven't used the VLIDE). Anyway, back to the ssget expression, the quote ( ' ) is used as there aren't any expressions in the list that require evaluation - the list can be taken as a literal. See here for a better explanation of the use of the apostrophe in these cases. The filter list is structured in much the same way as the DXF Data of an entity, as returned by the entget function, i.e. an association list of dotted pairs (see this return using this). With this knowledge we could construct the filter list in the following alternate way: (ssget "_X" (list (cons 0 "TEXT,MTEXT"))) As the cons function will return a dotted pair if supplied with two atoms (you can check what constitutes an atom using the atom predicate function). Another way would be: (ssget "_X" (list '(0 . "TEXT,MTEXT"))) This time supplying the literal dotted pair as an argument for the list function. In this case, all these methods are equivalent and will return the same result. This changes should we require expressions to be evaluated in the filter list. Consider the following example: (if (setq hgt (getdist "\nSpecify Text Height: ")) (sssetfirst nil (ssget "_X" (list (cons 0 "TEXT,MTEXT") (cons 40 hgt)))) ) In this case, we cannot quote the entire filter list, as the 'hgt' variable would not be evaluated. The list could alternatively be constructed thus: (if (setq hgt (getdist "\nSpecify Text Height: ")) (sssetfirst nil (ssget "_X" (list '(0 . "TEXT,MTEXT") (cons 40 hgt)))) ) As the first dotted pair doesn't contain expressions which require evaluation. Anyway, that's enough of my rambling - if you have any questions about my post, just ask. Merry Christmas! Lee Quote
David Bethel Posted December 19, 2010 Posted December 19, 2010 This would do the same thing: (setq a "*TEXT") (setq mytxt (ssget (list (cons 0 a)))) a is evaluated because the single quote has been replaced with a (list) call and the dotted pair is replaced with the (cons) call I suppose 0."*text" is between double brackets because one pair is from the list and the other two are bound the way autocad considers entities? It is the way autocad stores it's data. Autocad entities are really no more that a database. 0 is the field name (or DXF group code ). "TEXT" is the record value. The dotted pair is unique to Autocad. Common LISP doesn't have it. Is the " * " character used so all type of text is included?( single and mtext?)Correct "*POLYLINE" Would filter all POLYILNEs, Light or Heavy add "X' to the ssget call to select all text entities I see LeeMac is a faster typist -David Quote
Lee Mac Posted December 19, 2010 Posted December 19, 2010 I see LeeMac is a faster typist I think we just about covered it all between us Quote
Sittingbull Posted December 19, 2010 Author Posted December 19, 2010 Thanks a lot for the lesson, both of you. Anyway, that's enough of my rambling - if you have any questions about my post, just ask. You can be sure about that :wink:. After i've studied some more... . Been experimenting and reading all day, time to chill a bit... C ya! Quote
Sittingbull Posted January 19, 2011 Author Posted January 19, 2011 Surely it can be optimized. I've uploaded a file to test it with. Waiting for comments. 4417_MLIST.dwg ;;;Update Material lists ;;----------------------------------------------------------------------- ;;Prepare needed Layers (Defun c:prepl () (if (not (tblsearch "layer" "GE_TXT_LANGUAGE_EN")) (command "._layer" "m" "GE_TXT_LANGUAGE_EN" "co" "8" "" "") (princ "layer GE_TXT_LANGUAGE_EN exist! " ) ) (if (not (tblsearch "layer" "GE_TXT_LANGUAGE_FR")) (command "._layer" "m" "GE_TXT_LANGUAGE_FR" "co" "8" "" "") (princ "layer GE_TXT_LANGUAGE_FR exist! " ) ) (if (not (tblsearch "layer" "GE_TXT_LANGUAGE_DU")) (command "._layer" "m" "GE_TXT_LANGUAGE_DU" "co" "8" "" "") (princ "layer GE_TXT_LANGUAGE_DU exist! " ) ) (if (not (tblsearch "layer" "GE_TXT_LANGUAGE_GE")) (command "._layer" "m" "GE_TXT_LANGUAGE_GE" "co" "8" "" "") (princ "layer GE_TXT_LANGUAGE_GE exist! " ) ) (if (not (tblsearch "layer" "LA_MATLIST_TXT")) (command "._layer" "m" "LA_MATLIST_TXT" "co" "9" "" "") (princ "layer LA_MATLIST_TXT exist! " ) ) (if (not (tblsearch "layer" "LA_MATLIST_FRAME")) (command "._layer" "m" "LA_MATLIST_FRAME" "co" "9" "" "") (princ "layer LA_MATLIST_FRAME exist! " ) ) ) ;;------------------------------------------------------------------------ ;;Set Layer "0" current layer (Defun c:setl0c () (command "clayer" 0) ) ;;------------------------------------------------------------------------ ;;Replace layers (Defun c:replays () (if (not (tblsearch "layer" "ENG"))(princ "ENG layer does not exist! ") (setq leng (ssget "X" (list (cons 8 "ENG")))) ) (if leng (command "._chprop" leng "" "LA" "GE_TXT_LANGUAGE_EN" "") ) (if (not (tblsearch "layer" "FR"))(princ "FR layer does not exist! ") (setq lfr (ssget "X" (list (cons 8 "FR")))) ) (if lfr (command "._chprop" lfr "" "LA" "GE_TXT_LANGUAGE_FR" "") ) (if (not (tblsearch "layer" "NL"))(princ "NL layer does not exist! ") (setq lnl (ssget "X" (list (cons 8 "NL")))) ) (if lnl (command "._chprop" lnl "" "LA" "GE_TXT_LANGUAGE_DU" "") ) (if (not (tblsearch "layer" "DUITS"))(princ "DUITS layer does not exist! ") (setq lge (ssget "X" (list (cons 8 "DUITS")))) ) (if lge (command "._chprop" lge "" "LA" "GE_TXT_LANGUAGE_GE" "") ) (if (not (tblsearch "layer" "STUKL"))(princ "STUKL layer does not exist! ") (setq lstukl (ssget "X" (list (cons 8 "STUKL")))) ) (if lstukl (command "._chprop" lstukl "" "LA" "LA_MATLIST_TXT" "") ) (setq ss (ssget "x" (list (cons 0 "*line")))) (command "._chprop" ss "" "LA" "LA_MATLIST_FRAME" "") ) Quote
BIGAL Posted January 20, 2011 Posted January 20, 2011 Just a suggestion i would have created a list of layer names 4 as per above and then just used repeat 4 to check for the layer in one single defun rather than copying and changing 4 times plus 2 more for the mat_lst layers you could set colour to 8 then when more than 4 change to 9. thinking a bit more you could put the check layer defun in a autoloaded external lisp so its available then for any future programs you write also. (mytblsearch) variables = layername & laycol Maybe also layername,layercol,layerlinetype as list. just pull apart line for 3 variables. Found this lay_search is layer name for checking lay_colour is layer colour L_type is linetype ; check for missing layers on the fly (defun lay_miss () (if (= l_type nil)(setq l_type "continuous")) (setvar "cmdecho" 0) (setq lay_ans (cdr (assoc 2 (tblsearch "LAYER" lay_search)))) (if (= lay_ans nil) (command "layer" "n" lay_search "c" lay_colour lay_search "l" l_type lay_search "") (command "layer" "t" lay_search "") ) (setq lay_ans nil) ) Quote
Sittingbull Posted February 2, 2011 Author Posted February 2, 2011 Absolutely. This lisp just does the trick for now. But i'll write a better one in time Thx for the suggestions. i'll defenetly take it in consideration. Quote
Recommended Posts
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.