Ament Posted September 8, 2017 Share Posted September 8, 2017 Hello, First of all, I'm quiet new to lisp (one week of self study to create my first automation) but on this point I'm stuck My usecase: I got a drawing from a supplier and want to modify some objects based on their layer. Unfortunately I have only a list of layer which are of interest for me and could be in the drawing, but not all of them are in every drawing from that supplier. Additional there are some objects in the drawing on layers which are not to be modified An example for better understanding: Layer to be modified are in a list: (setq ltbm (list "131" "144" "154" "204" "Furniture" "Water")) In the first drawing are the following layer: (list "1" "17" "131" "204" "Stone" "Furniture") Second drawing has other layer in use: (list "5" "76" "144" "154" "204" "Air" "Water") The Problem: First: I need to find out which of the interesting layer are used. In the first case: (list "131" "204" "Furniture") And in second case: (list "144" "154" "204" "Water") And second: I need to select all objects on that layers. If I do the selection command manually. For the first case it would be: (ssget mod (ssget "_X" '((-4 . )))) While in second case: (ssget mod (ssget "_X" '((-4 . )))) With the selection set mod I can go ahead myself. So my issues are: How to find out the layers which are used in the drawing. Than how to get the subset of layer which are of interest to me. And than how to get the selection of objects on these layers done. I hope someone can help me out there. Would be so much appreciated. Best regards, Markus Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted September 8, 2017 Share Posted September 8, 2017 The ssget filter can contain layers that do not exist in the drawing. So much of what you are trying to do is not necessary. But checking if ssget returns a selection set instead of nil is generally advisable: (if (setq mod (ssget "_X" (8 . "131,144,154,204,Furniture,Water"))) (progn ; Do something ) ) To check if a layer exists you can use this: (tblobjname "layer" "Water") Quote Link to comment Share on other sites More sharing options...
Ament Posted September 8, 2017 Author Share Posted September 8, 2017 Oh, really. It works without that nasty OR too. When I tried to put some layer not existing in my code before it returned an error. Looks like I'll have to doublecheck once again when I'm back at the company If the solution is that easy it would be really great!! Thank you in advance!! Quote Link to comment Share on other sites More sharing options...
BIGAL Posted September 9, 2017 Share Posted September 9, 2017 You can use your list of layers and add a bit to Roy_043 suggestion at the alert you could do a add layer etc. (setq ltbm (list "131" "144" "154" "204" "Furniture" "Water")) (repeat (setq x (length ltbm)) (setq chk (tblobjname "layer" (nth (setq x (- x 1)) ltbm))) (if (= chk nil) (Alert (strcat "your layer " (nth x ltbm) " " "is missing")) (princ (strcat "\n" (nth x ltbm))) ) ) Quote Link to comment Share on other sites More sharing options...
Ament Posted September 11, 2017 Author Share Posted September 11, 2017 Oh no, If I'm using the code like Roy_043 suggested I get an error while loading the lisp. Corrupt Argument Type: consp "131, 144, 154, 204, Furniture, Water" Some ideas how to solve it? Quote Link to comment Share on other sites More sharing options...
Aftertouch Posted September 11, 2017 Share Posted September 11, 2017 (edited) This code does something with all objects on the found layers, defined as 'mod' (defun C:CadTutor ( / ) (setq layerslist (list "layer1" "layer2" "layer3" "layer4")) (foreach layer layerslist (if (/= (tblsearch "LAYER" layer) nil) (progn (setq mod (ssget "_X" (list (cons 8 layer)))) ; selects all object on the found layers ; Code here to do something with the found layers ) (progn (princ (strcat "\nLayer: " layer " not found in drawing")) ) ) ) (princ) ) Edited September 11, 2017 by Aftertouch Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted September 11, 2017 Share Posted September 11, 2017 Oh no, If I'm using the code like Roy_043 suggested I get an error while loading the lisp. Corrupt Argument Type: consp "131, 144, 154, 204, Furniture, Water" Some ideas how to solve it? Oops, my bad. The code should be: (if (setq mod (ssget "_X" '((8 . "131,144,154,204,Furniture,Water")))) (progn ; Do something ) ) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 11, 2017 Share Posted September 11, 2017 This code does something with all objects on the found layers, defined as 'mod' Good one. I just commented a few statements / codes for your reference and hope you don't mind. (defun C:CadTutor ( / [color="blue"]layerslist mod[/color] ) [color="red"];; localizing variables is very important unless any is needed to be global.[/color] (setq layerslist (list "layer1" "layer2" "layer3" "layer4")) (foreach layer layerslist (if (/= (tblsearch "LAYER" layer) nil) [color="red"];; if statement is equal to this: (if (tblsearch "LAYER" layer) ..... )[/color] (progn (setq mod (ssget "_X" (list (cons 8 layer)))) ; selects all object on the found layers ; Code here to do something with the found layers ) (progn [color="red"];; There is no need to progn function since you have only one expression.[/color] (princ (strcat "\nLayer: " layer " not found in drawing")) ) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
Ament Posted September 11, 2017 Author Share Posted September 11, 2017 Unfortunately the solution of Roy isn't working as expected. It always return nil. Maybe because it is looking for a layer with the characters in the quotes. But the way Aftertouch proposed is working well for me. Thank you so much! Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted September 11, 2017 Share Posted September 11, 2017 @Ament: I don't understand your comment. The layers in the ssget filter match those supplied by you in the OP. Of course you would have to change them if they no longer apply. And of course you have to add code where I have put "Do something". Just copy-pasting the code will return nil. Try: (if (setq mod (ssget "_X" '((8 . "131,144,154,204,Furniture,Water")))) (progn (princ (strcat "\n" (itoa (sslength mod)) " entities in selection set ")) (princ) ; Do something ) ) Quote Link to comment Share on other sites More sharing options...
Aftertouch Posted September 11, 2017 Share Posted September 11, 2017 @ Ament, your welcome, also take a look at Tharwats comments. He is totaly right about the red parts. @Tharwat, Thanks for the additions, i was a bit to 'quick and dirty'. :-) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 11, 2017 Share Posted September 11, 2017 @Tharwat, Thanks for the additions, i was a bit to 'quick and dirty'. :-) No worries, keep on the good work. Quote Link to comment Share on other sites More sharing options...
Ament Posted September 12, 2017 Author Share Posted September 12, 2017 Hi Roy, if i use the command: (setq mod (ssget "_X" '((8 . "131,144,154,204,Furniture,Water")))) it returns nil. At least to me in AutoCAD2016. Sure, the layer are still the one include in the drawing It should find about 20.000 objects Thats why I thought it may search for objects on one layer with the name 131,144,154,204,Furniture,Water and doesn't look for 6 layer. Your Idea was my favorit one because it does everyting in one selection. Now I get the result with one turn per layer, but at least it is the right result. Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted September 12, 2017 Share Posted September 12, 2017 @Ament: The code should work in AC2016 as well. Something else must be wrong. Maybe Aftertouch or Tharwat can jump in to clarify. I use BricsCAD instead of AutoCAD. Quote Link to comment Share on other sites More sharing options...
Aftertouch Posted September 12, 2017 Share Posted September 12, 2017 When i use the code below, it returns a selection set of the object when... There are objects in the modelspace on that layer. When the layer is 'hidden' in a block the code below does not find the lines. (setq mod (ssget "_X" '((8 . "131,144,154,204,Furniture,Water")))) I think Ament has the element inside blocks? Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 12, 2017 Share Posted September 12, 2017 @Ament, Can you upload the drawing that you are currently running the codes on? Quote Link to comment Share on other sites More sharing options...
Ament Posted September 13, 2017 Author Share Posted September 13, 2017 Hello everyone, The elements are not inside a block. I'm sure about it because I run the code to set all blocks to be explodable and the explode all before Unfortunately I can't share the drawing as they are confidential. I gave it another try by typing it by hand into the command bar. It gives me a selection set! But if I put it to a simple code it's giving me nil.. strange.. (defun c:dellay (/ mod) (setq mod (ssget "_X" '((8 . "131,133,134,SomeMore")))) (command "._Erase" mod "") ) Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted September 13, 2017 Share Posted September 13, 2017 The command function always returns nil. Quote Link to comment Share on other sites More sharing options...
Ament Posted September 13, 2017 Author Share Posted September 13, 2017 Sure, but it is not deleteing the objects before. Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted September 14, 2017 Share Posted September 14, 2017 Verify that the objects are on unlocked layers and that they are in the current space. Quote Link to comment Share on other sites More sharing options...
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.