SteveK Posted July 3, 2009 Posted July 3, 2009 This is a general question I'm hoping to be able to use in lots of lisps. The line: (setq ss (ssget "_X" filtered_list) searches for all objects based on the filter_list within modelspace or paperspace. How do you make it search include everything; in all blocks? and in all sheets? Is there a simple answer...? Ta Quote
The Buzzard Posted July 3, 2009 Posted July 3, 2009 This is a general question I'm hoping to be able to use in lots of lisps. The line: (setq ss (ssget "_X" filtered_list) searches for all objects based on the filter_list within modelspace or paperspace. How do you make it search include everything; in all blocks? and in all sheets? Is there a simple answer...? Ta Hey steve1, Check out these links for most of your answers: http://www.cadtutor.net/forum/showthread.php?t=31499 http://www.afralisp.net/lispa/lisp19.htm http://www.afralisp.net/lisp/filter.htm Good Luck, The Buzzard Quote
SteveK Posted July 3, 2009 Author Posted July 3, 2009 Ok thanks, I'll have a look and let you know. Quote
SteveK Posted July 3, 2009 Author Posted July 3, 2009 Had a quick browse of those links... sounds like there's no simple method. Basically if I wanted to find all green lines everywhere I'd have to step through each entity. Quote
Lee Mac Posted July 3, 2009 Posted July 3, 2009 Had a quick browse of those links... sounds like there's no simple method. Basically if I wanted to find all green lines everywhere I'd have to step through each entity. If you are referring to entities within blocks, you will need to shuffle through the block definition. Here is an example code: (defun c:test () (GetObj (tblobjname "BLOCK" <blockname>)) ) ; Get Sub-Entities from Table Def (defun GetObj (bObj) (if (setq bObj (entnext bObj)) (cons bObj (GetObj bObj)))) The above, if supplied with a valid block table entity will shuffle through the block definition and return a list of all the entities that make up the block. Quote
SteveK Posted July 6, 2009 Author Posted July 6, 2009 (defun c:test () (GetObj (tblobjname "BLOCK" <blockname>)) ) ; Get Sub-Entities from Table Def (defun GetObj (bObj) (if (setq bObj (entnext bObj)) (cons bObj (GetObj bObj)))) The above, if supplied with a valid block table entity will shuffle through the block definition and return a list of all the entities that make up the block. Ok I'm trying to implement this tblobjname to shuffle through the code but I'm still trying to get to terms with it. (and it's such simple code!! ) This is probably really stupid to do but I'm just trying to understand; if I pick the same block using both: (setq ENT (car(entsel))) ;;;And (tblobjname "BLOCK" (cdr (assoc 2 (entget(ENT)))) Obviously they both return the same entity names. So how does tblobjname get down into the sub-entities of the block? With the form GetObj you are going through all the entities until they run out (setq bObj (entnext (bObj)). So can I put something like that into a while loop and then go ahead and fill the while loop with modifications? To keep it simple, change color Green to color Yellow: (While (setq bObj (entnext (bObj))) (If (= (cdr (assoc 62 bObj)) 3) (setq bObj (subst (cons 62 2) (assoc 62 bObj) bObj)) ) ) This doesn't work but you get the idea... Quote
Lee Mac Posted July 6, 2009 Posted July 6, 2009 The tblobjname gets entity name of a specified table entry and is slightly different from that entity returned from (car (entsel)) in the fact that you can step through the block components (inaccessible through the Object Entity name. I would be inclined to use the Sub-function to retrieve yourself a list of entities, as lists are a lot easier to deal with, and to error trap for. Keeps things simple that way. Lee Quote
SteveK Posted July 6, 2009 Author Posted July 6, 2009 Regarding tblobjname, (Sorry I still haven't got my head around it) how does it step through block components? From help file: (tblobjname table-name symbol) What sorts of things can symbol be? If I have a block that has a line in it, can that be specified in the symbol bit (with table-name = "BLOCK")? Thanks Quote
The Buzzard Posted July 6, 2009 Posted July 6, 2009 Regarding tblobjname, (Sorry I still haven't got my head around it) how does it step through block components? From help file: (tblobjname table-name symbol) What sorts of things can symbol be? If I have a block that has a line in it, can that be specified in the symbol bit (with table-name = "BLOCK")? Thanks Hey Steve, A symbol can be any type entity. Shown below is a list of a block and lwpolyline. The entity name as you can see is within those lists. It is shown as dxf data here for example. Here is a list for a block: (-1 . <Entity name: 7ef6f508>) (0 . "INSERT") (330 . <Entity name: 7ef6dcf8>) (5 . "4C1") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "T-COMM-TAPP") (100 . "AcDbBlockReference") (66 . 1) (2 . "SPEC_2-WAY") (10 0.972767 0.795854 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.785398) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0) Here is a lwpolyline: (-1 . <Entity name: 7ef6f5d8>) (0 . "LWPOLYLINE") (330 . <Entity name: 7ef6dcf8>) (5 . "543") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbPolyline") (90 . 2) (70 . 0) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 1.66837 -0.629099) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 3.45399 -0.0267465) (40 . 0.0) (41 . 0.0) (42 . 0.0) (210 0.0 0.0 1.0) Quote
The Buzzard Posted July 6, 2009 Posted July 6, 2009 In the situation of the block for example. (tblobjname table-name symbol) Command: (tblobjname "block" "SPEC_2-WAY") would return Quote
Lee Mac Posted July 6, 2009 Posted July 6, 2009 The Symbol argument is just the identifier for the table entry, so in the case of a block, its name. The tblobjname will get the BLOCK entity name, as opposed to the INSERT entity name (as retrieved by entsel). For example, I use these as references when creating LISPs, take a look at the different returns from each: (defun c:on (/ ent) (if (setq ent (car (entsel "\nSelect Object: "))) (progn (foreach n (entget ent) (print n)) (textscr))) (princ)) (defun c:layen (/ lay tdef) (if (and (snvalid (Setq lay (getstring t "\nSpecify Layer: "))) (setq tdef (tblsearch "LAYER" lay))) (progn (princ "\n-- Table Definition --\n") (foreach x tdef (print x)) (princ "\n\n-- LAYER Object -- \n") (foreach x (entget (tblobjname "LAYER" lay)) (print x)) (textscr)) (princ "\n<< Layer not Found >>")) (princ)) (defun c:blken (/ blk tdef) (if (and (snvalid (setq blk (getstring t "\nSpecify Block Name: "))) (setq tdef (tblsearch "BLOCK" blk))) (progn (princ "\n-- Table Definition --\n") (foreach x tdef (print x)) (princ "\n\n-- BLOCK Object -- \n") (foreach x (entget (tblobjname "BLOCK" blk)) (print x)) (textscr)) (princ "\n<< Block not Found >>")) (princ)) Once you have the BLOCK entity name, you can use entnext to step through the various entities that make up the block in question. Just as, to create a block using entmake you would first create the BLOCK entity: (entmake (list (cons 0 "BLOCK") (cons 2 <Block Name>) etc (entmake (list (cons 0 "LINE") (cons... etc etc (entmake (list (cons 0 "ENDBLK") (cons 8 "0") ) ) And finish with an ENDBLK, when using the TblObjName entity, you are just retrieving the BLOCK entity, then stepping through (getting the LINE in this case), until you reach the ENDBLK which will return nil... Hope this helps Lee Quote
SteveK Posted July 7, 2009 Author Posted July 7, 2009 My thanks to you both, I think I'm sortof understanding it! That last bit of code clicked; "BLOCK" is the first sub-entity: (entmake (list (cons 0 "BLOCK") (cons 2 ) etc (entmake (list (cons 0 "LINE") (cons... etc etc (entmake (list (cons 0 "ENDBLK") (cons 8 "0") ) ) Anyways, so now using Lee's code and the example of changing green entities to red here's what I got: (defun c:blk_mod (/ inside_ents en enlist) (setq inside_ents (GetObj (tblobjname "BLOCK" (cdr (assoc 2 (entget (car (entsel)))))))) (while (setq en (car inside_ents)) (setq enlist (entget en)) (If (= (cdr (assoc 62 enlist)) 3) (Progn (setq enlist (subst (cons 62 1) (assoc 62 enlist) enlist)) (entmod enlist) (entupd en) ) ) (setq inside_ents (cdr inside_ents)) ) ; End While (command "REGEN" "") (princ) ) ; Get Sub-Entities from Table Def (defun GetObj (bObj) (if (setq bObj (entnext bObj)) (cons bObj (GetObj bObj)))) I'm sure it's not the best way to do it but it works. Now all I got to do is somehow apply it to all blocks in the drawing and it'll be sweet. I'll post it later I just don't have time at the moment. Thanks ps. how do you copy code on this forum that maintains the colours from vlisp? Quote
Lee Mac Posted July 7, 2009 Posted July 7, 2009 I'm sure it's not the best way to do it but it works. Now all I got to do is somehow apply it to all blocks in the drawing and it'll be sweet. I'll post it later I just don't have time at the moment. Hey Steve, I would approach only very slightly different, allowing for a missed pick: [b][color=RED]([/color][/b][b][color=BLUE]defun[/color][/b] c:blk_mod [b][color=RED]([/color][/b][b][color=BLUE]/[/color][/b] ent elst[b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] ent [b][color=RED]([/color][/b][b][color=BLUE]car[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]entsel[/color][/b] [b][color=#ff00ff]"\nSelect a Block: "[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]foreach[/color][/b] sub [b][color=RED]([/color][/b]getObj [b][color=RED]([/color][/b][b][color=BLUE]tblobjname[/color][/b] [b][color=#ff00ff]"BLOCK"[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cdr[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]assoc[/color][/b] [b][color=#009900]2[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]entget[/color][/b] ent[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] elst [b][color=RED]([/color][/b][b][color=BLUE]entget[/color][/b] sub[b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]eq[/color][/b] [b][color=#009900]3[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cdr[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]assoc[/color][/b] [b][color=#009900]62[/color][/b] elst[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]progn[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]entmod[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]subst[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] [b][color=#009900]62[/color][/b] [b][color=#009900]1[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]assoc[/color][/b] [b][color=#009900]62[/color][/b] elst[b][color=RED])[/color][/b] elst[b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]entupd[/color][/b] sub[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]command[/color][/b] [b][color=#ff00ff]"_regenall"[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]princ[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; Get Sub-Entities from Table Def[/color][/i] [b][color=RED]([/color][/b][b][color=BLUE]defun[/color][/b] GetObj [b][color=RED]([/color][/b]bObj[b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] bObj [b][color=RED]([/color][/b][b][color=BLUE]entnext[/color][/b] bObj[b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] bObj [b][color=RED]([/color][/b]GetObj bObj[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] Also, bear in mind that this will only alter the colours of those not set to BYLAYER or BYBLOCK. As for applying to every block, you would need to cycle through every block in the table, perhaps use something like this: [b][color=RED]([/color][/b][b][color=BLUE]defun[/color][/b] getblk [b][color=RED]([/color][/b][b][color=BLUE]/[/color][/b] tdef lst[b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]reverse[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]while[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] tdef [b][color=RED]([/color][/b][b][color=BLUE]tblnext[/color][/b] [b][color=#ff00ff]"BLOCK"[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]not[/color][/b] tdef[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] lst [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cdr[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]assoc[/color][/b] [b][color=#009900]2[/color][/b] tdef[b][color=RED])[/color][/b][b][color=RED])[/color][/b] lst[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] The above will return a list of all blocks in the table, which you could use with foreach. ps. how do you copy code on this forum that maintains the colours from vlisp? I wrote myself a LISP to add the specific [ color] [/color] tags to the code before posting Lee Quote
SteveK Posted July 7, 2009 Author Posted July 7, 2009 Ahh very good I've gotta learn to use foreach function. And I never thought to put the entmod before the subst rather than "(setq elst" with entmod at the end. I'll try give getblk a go sometime today. Just an aside about the colors. I notice the only difference between an RGB Blue colour and ACI Blue is in the entity it has (420 . 255). Is there a way to delete this item in the entity list? I was thinking just creating a loop and making a new list with a catch when it gets to 420, then replacing the entity, if there is no other way. ps. are there any other Luminous Beings here? Congrats! Quote
SteveK Posted July 8, 2009 Author Posted July 8, 2009 Thanks for your help, but now I've gotten stuck quite early on with selecting all blocks. Lee's code: (defun getblk (/ tdef lst) (reverse (while (setq tdef (tblnext "BLOCK" (not tdef))) (setq lst (cons (cdr (assoc 2 tdef)) lst))))) Outputs the names of all the blocks but I'm after the entity names. Now (cdr (assoc -2 (tblnext "BLOCK" T))) (not +2) outputs an entity name but it is not the same entity as you'd get from (car(entsel)) (the block entity) and it's not the same entity as you'd get from (tblobjname "BLOCK" ) (the first sub-block entity). Do you know what it is? Thanks Quote
Lee Mac Posted July 9, 2009 Posted July 9, 2009 Hey Steve, Sorry for the late reply mate, been busy past few days. I've gotta learn to use foreach function. Foreach isn't too difficult, very intuitive in fact. Format it like this: (foreach [i][color=Red]<symbol>[/color][/i] [color=Red][i]<list>[/i][/color] [color=Red][i]<functions...etc>[/i][/color] The symbol represents an item in the provided list - the symbol can be called what you like (except already existing function names etc of course). Hence, as an example: (foreach x '(1 2 3) (setq lst (cons (1+ x) lst)) ) Would set the variable lst to: (4 3 2). In this case our symbol is just "x", representing 1, 2 and 3 in turn. Just an aside about the colors. I notice the only difference between an RGB Blue colour and ACI Blue is in the entity it has (420 . 255). Is there a way to delete this item in the entity list? I was thinking just creating a loop and making a new list with a catch when it gets to 420, then replacing the entity, if there is no other way. I suppose just something like this would do: (entmod (vl-remove-if (function (lambda (x) (eq 420 (car x)))) (entget ent))) ps. are there any other Luminous Beings here? Congrats! Only me and ReMark - only difference is, I joined two years later than him... Thanks for your help, but now I've gotten stuck quite early on with selecting all blocks.Lee's code: (defun getblk (/ tdef lst) (reverse (while (setq tdef (tblnext "BLOCK" (not tdef))) (setq lst (cons (cdr (assoc 2 tdef)) lst))))) Outputs the names of all the blocks but I'm after the entity names. Now (cdr (assoc -2 (tblnext "BLOCK" T))) (not +2) outputs an entity name but it is not the same entity as you'd get from (car(entsel)) (the block entity) and it's not the same entity as you'd get from (tblobjname "BLOCK" ) (the first sub-block entity). Do you know what it is? Thanks I believe it is the first sub-entity of the block definition, i.e. the one after the "BLOCK BEGIN". I suppose to iterate through all blocks, you could use something like: (defun c:test (/ elst) (foreach blk (getblk) (foreach sub (GetObj (tblobjname "BLOCK" blk)) (if (eq 3 (cdr (assoc 62 (entget sub)))) (progn (setq elst (entget sub)) (entmod (subst (cons 62 1) (assoc 62 elst) elst)) (entupd sub))))) (princ)) (defun GetObj (bObj) (if (setq bObj (entnext bObj)) (cons bObj (GetObj bObj)))) (defun getblk (/ tdef lst) (reverse (while (setq tdef (tblnext "BLOCK" (not tdef))) (setq lst (cons (cdr (assoc 2 tdef)) lst))))) Or even possibly: (defun c:test2 () (vl-load-com) (foreach sub (mapcar 'vlax-ename->vla-object (apply 'append (mapcar 'GetObj (getblk)))) (if (eq 3 (vla-get-color sub)) (vla-put-color sub 1))) (princ)) (defun GetObj (bObj) (if (setq bObj (entnext bObj)) (cons bObj (GetObj bObj)))) (defun getblk (/ tdef lst) (reverse (while (setq tdef (tblnext "BLOCK" (not tdef))) (setq lst (cons (tblobjname "BLOCK" (cdr (assoc 2 tdef))) lst))))) Hope this helps in some way, Lee Quote
SteveK Posted July 9, 2009 Author Posted July 9, 2009 Ahh that helps heaps! It's fixed; I can't believe how easy it is now that I see it. There's no need to get the entity name when it's just as easy using the block name. I still have understanding-issues with getting into sub-entities with entnext etc, but I'll keep studying up on it some more. For the time being though, thanks a lot! Quote
Lee Mac Posted July 9, 2009 Posted July 9, 2009 Glad to have helped, if you get stuck on anything else, just ask Lee Quote
SteveK Posted July 13, 2009 Author Posted July 13, 2009 The "test" form (posted by Lee) works a treat except when tried on a large drawing (with over 100 table blocks) in which case it came back with: Hard error occurred *** internal stack limit reached (simulated) I'm thinking because it's a memory issue the act of compiling a list of all entities within all blocks would be the cause. Hence it probably means this method of affecting all blocks is not suitable for large drawings (with many blocks). Any thoughts? Quote
Lee Mac Posted July 13, 2009 Posted July 13, 2009 The "test" form (posted by Lee) works a treat except when tried on a large drawing (with over 100 table blocks) in which case it came back with: Hard error occurred *** internal stack limit reached (simulated) I'm thinking because it's a memory issue the act of compiling a list of all entities within all blocks would be the cause. Hence it probably means this method of affecting all blocks is not suitable for large drawings (with many blocks). Any thoughts? The method I am using for compiling the list of block entities is recursive, and so is limited by the stack, so it will fail on large operations. I will provide you with another option 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.