Jump to content

Lisp to sort our not existing layer from list and create selection using the existing


Ament

Recommended Posts

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

Link to comment
Share on other sites

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")

Link to comment
Share on other sites

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!!

Link to comment
Share on other sites

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)))
)
)

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 by Aftertouch
Link to comment
Share on other sites

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
 )
)

Link to comment
Share on other sites

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)
)

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

@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
 )
)

Link to comment
Share on other sites

@ 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'. :-)

Link to comment
Share on other sites

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. ;)

Link to comment
Share on other sites

@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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 "")
)

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...