Author Topic: easy filter  (Read 8383 times)

0 Members and 1 Guest are viewing this topic.

rude dog

  • Guest
easy filter
« on: July 09, 2004, 09:01:59 PM »
Command: (setq ss (ssget '(0 . "LINE")(6 . "Continuous"))))
; error: bad argument type: consp "Continuous"
Code: [Select]

I'm trying to make a sel set of "lines" that are "continuous" no matter what i capture in a crossing window....this line of code does not seem to work
any idea's on a friday evening ...boy 4-5 years ago this would be the last thing i would be thinking about on a friday evening.....   :shock:

rude dog

  • Guest
easy filter
« Reply #1 on: July 09, 2004, 09:18:17 PM »
ok..it seems to work better with :
Code: [Select]

(setq ss (ssget '[b]([/b](0 . "LINE")(6 . "Continuous"))))

but shouldn't it echo back to you the selection set name?

rude dog

  • Guest
easy filter
« Reply #2 on: July 09, 2004, 09:20:40 PM »
sorry
this is what the code should look like:
Code: [Select]

(setq ss (ssget '((0 . "LINE")(6 . "Continuous"))))

but I still dont believe it is working properly cuz it does echo back the selection set name?....

rude dog

  • Guest
easy filter
« Reply #3 on: July 09, 2004, 10:20:39 PM »
but I still dont believe it is working properly cuz it does not echo back the selection set name?....or give me a sslength[/i][/b]

rude dog

  • Guest
easy filter
« Reply #4 on: July 09, 2004, 11:25:03 PM »
wow i have talked to myself long enuf to realize i have to omitt
the (6. "continuous") in the code....i guess the only other way is focus on a specific layer name....that sucks....is there any other way of doing it by
entity type: "line"     and         linetype: "continuous"  :?:
time for cerveza
lata

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #5 on: July 10, 2004, 12:38:06 AM »
Works for me..

Code: [Select]
_$ (setq ss (ssget "X" '((0 . "LINE") (6 . "Continuous"))))
<Selection set: 4>
_$


Maybe you should add the "X" 8)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

rude dog

  • Guest
easy filter
« Reply #6 on: July 10, 2004, 12:49:15 AM »
that be it  :oops:

Anonymous

  • Guest
easy filter
« Reply #7 on: July 10, 2004, 01:06:12 AM »
man I dont know whats going on but I have two lines drawn that should make up the slecetion set and two that should not (only 4 lines drawn on the screen and nothing else)and this is what i get when i run the line of code:
Code: [Select]

Command: (setq ss (ssget "X" '((0 . "LINE") (6 . "Continuous"))))
nil



is there some magical value I need to change maybe.....

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
easy filter
« Reply #8 on: July 10, 2004, 01:11:50 AM »
After re-reading the first post, and the last post, I am confused....

The first post said that the selection set should be selected via crossong window, the "X" option selects all objects in the drawing....

The problem with your code is one that is easily overlooked by someone not familiar with the way entity data lists are written and stored. For ALL objects in the drawing there is a DXF code that applies for linetype, BUT that DXF code is optional and is not included on ANY objects set to BYLAYER. As such you cannot filter for that linetype on objects set to bylayer. This holds true for color AND linetype.

In order to effectively setup a filter for a linetype that is bylayer, would be to select al the objects and selectively remove them based on the DXF 6 codes and the layer setting.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

rude dog

  • Guest
easy filter
« Reply #9 on: July 10, 2004, 01:19:40 AM »
Quote
The first post said that the selection set should be selected via crossong window, the "X" option selects all objects in the drawing....


I did say this but then i realized it could not be done the i was approaching it
I will now have to filter with entity type "line" and probably a specific layer name.
that avatar is gunna give me nightmares 2nite <clicking the lights back on>

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #10 on: July 10, 2004, 10:26:09 AM »
rude dog
So sorry I misread your request last night. :oops:  I should have been getting some sleep
as well. Keith is quite right as usual. :)
i thought you were looking for lines with 'Continuous' and not ByLayer that were
'Continuous'. Here is a routine to do what Keith was enplaning, select lines that are
'Continuous' or, 'ByLayer' and the layer is set to 'Continuous'.

Again sorry if I lead you astray.

Thanks Keith for catching that and see if I missed anything in the routine that needs attention.

Code: [Select]
;;  User select lines, returns a selection set of LINES
;;  with 'Continuous Line Type' or ByLayer with a layer
;;  with 'Continuous Line Type'
;;  Returns nil if none are selected or 'Continuous Line Type'
;;  NOTE: this routine leaves objects selected if nil is not returned.
(defun Get:Cont:Lines (/ ss ssnew idx ent elst linetype lltype)
  ;;  Get user to pick lines
  (prompt "\nSelect lines to find 'Continuous Type'.")
  (if (setq ss (ssget '((0 . "LINE"))))
    (progn ; got some LINES
      (setq idx (sslength ss) ; how many lines
            ssnew   (ssadd)   ; empty selection set
      )
      (prompt (strcat "\n" (itoa idx) " LINE objects selected."))
      ;;  test every entity in the selection set
      (while (>= (setq idx (1- idx)) 0)
        (setq ent     (ssname ss idx) ; entity name
              elst    (entget ent) ; entity list
              linetyp (cdr (assoc 6 elst)) ; entity line type, may be nil
              ;;  if it is nil then the layer line type is used
              lltype  (cdr(assoc 6
                           (tblsearch "layer"
                             (cdr (assoc 8 elst))))) ; layer linetype
        )
        ;;  test if line entity has "Continuous" line type
        ;;
        ;;  (OR line entity has "ByLayer" line type
        ;;     AND layer is set to "Continuous" line type)
        (if (or (= linetyp "Continuous")
                (and (null linetyp) ; if ByLayer
                     (= lltype "Continuous")
                )
            )
          (ssadd ent ssnew) ; collect the lines
        ) ; endif
      ) ; while
      (prompt (strcat "\n" (itoa (sslength ssnew))
                      " were LINES that type \"Continuous\" .\n"))
      (if (= (sslength ssnew)0)
        nil ; return nil
        ;;  =====   ELSE  ======
        (progn
          (sssetfirst nil ssnew) ; display the selected items
          ssnew ; return a new selection set, note the set may be empty
        ) ; progn
      ) ; endif
    ) ; progn
    ;; ====  ELSE  =======
    (prompt "\nNothing Selected."); returns nil
  ) ;endif
); defun

(defun c:test(/ ss)
  (setq ss (Get:Cont:Lines))
  (cond
    ((null ss)
     (prompt "\nReturn was nil")
    )
    ((= (sslength ss) 0)
     (prompt "\nSelection set empty")
    )
    ( (prompt "\nGot Selection set."))
  )
  (getpoint "\nPress any key to exit.")
  (print)
  (command) ; clear the selected items
  (sssetfirst nil) ; clear the grips
  (princ)
) ;defun test
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

rude dog

  • Guest
easy filter
« Reply #11 on: July 10, 2004, 11:48:11 AM »
cab works well dude.....I was thinking of doing something similar
this has laid down the blue print for me thanks for your time...... again  :)

SMadsen

  • Guest
easy filter
« Reply #12 on: July 10, 2004, 03:03:33 PM »
Quote from: Keith
As such you cannot filter for that linetype on objects set to bylayer.

While it's true that bylayer settings are not written to entity data lists, the SSGET filter mechanism does recognize "Bylayer" for linetypes and the number 256 for colors, meaning color "Bylayer".

(ssget "X" '((6 . "Bylayer")(62 . 256))) will return all objects with ltype and color as bylayer

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #13 on: July 10, 2004, 05:06:48 PM »
Very interesting, so you could use this to filter the selection set
the user picked to only lines with  Continuous or Bylayer.

Code: [Select]
(ssget '((0 . "LINE")(6 . "Continuous,Bylayer")))
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
easy filter
« Reply #14 on: July 10, 2004, 05:20:12 PM »
If "Continuous" is the object linetype you're after, yes. Somehow I think the initial quest was to filter objects of linetype Bylayer where "Continuous" is the layer linetype. If so then it could be an idea to search the layer table and apply the layers that fit to the filter along with '(6 . "bylayer")

Jeff_M

  • King Gator
  • Posts: 4094
  • C3D user & customizer
easy filter
« Reply #15 on: July 11, 2004, 12:10:34 PM »
Here's my spin on this. I collect the layer names that use the specified linetype and use those in the selection set filter, combined with the specified linetype filter for those entity types that don't use bylayer.

Returns the ss, so in the calling function to get "continuous" "line"s you'd do this:
(setq ss (get-ltype-ents "CONTINUOUS" "LINE")
or to get "dashed" "circle"s:
(setq ss (get-ltype-ents "DASHED" "CIRCLE"))

Code: [Select]

(defun  get-ltype-ents (ltype etype / doc layers laylist)
  (vl-load-com)
  (setq doc (vla-get-activedocument (vlax-get-acad-object))
layers (vla-get-layers doc))
  (vlax-for lay layers
    (if (not (wcmatch (vla-get-name lay) "*|*"));skip xref layers
      (if (= (vla-get-linetype lay) ltype)
(if (not laylist)
 (setq laylist (vla-get-name lay))
 (setq laylist (strcat laylist "," (vla-get-name lay)))
 )
)
      )
    )
  (princ "\nMake selection......")
  (setq ss (ssget (list (cons 0 etype) '(-4 . "<OR") (cons 6 ltype) (cons 8 laylist) '(-4 . "OR>"))))
  )

rude dog

  • Guest
easy filter
« Reply #16 on: July 14, 2004, 01:49:52 AM »
Jeff seen you jumped in to help thanks....I'm still pretty new to this stuff and havent messed with vlisp, objectARX...so some of your code is kinda foriegn to me but I think i get the jist of it.....Thanks for the help guys.
and CAB for getting off the ground...my huge problem area is error checking so if any one feels like chopping and dicing away...go for it...its how I'will learn...I know for a fact there is a razor sharp cleaver in denmark  :)
Code: [Select]

(defun c:gtl ()
(prompt "\nSelect continuous ltype lines to filter ")
(setq 1ss (ssget '((0 . "Line"))))
(setq Lss (sslength 1ss))
(setq ssgrp (ssadd))
(setq cntr 0)
(while (< cntr Lss) (setq entnam (entget (ssname 1ss cntr)))
(setq Ln (cdr (assoc 8 entnam)))
(setq ssnam (cdr (assoc 6 (tblsearch "Layer" (eval Ln)))))
(if (= ssnam "Continuous")
(progn
(setq entnam (cdr (assoc -1 entnam)))
(setq ssgrp (ssadd entnam ssgrp))))
(setq cntr (1+ cntr)))
(prompt " \n To access filtered selection set: <!ssgrp> ")
(princ)
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #17 on: July 14, 2004, 08:15:21 AM »
Good job Rude Dog.
A few comments from me. The routine works, that is good. :)
There are many ways to accomplish the same thing so it
may be the way someone likes to write the code which is
coders preference. Also these small routines tend to have
minimal error checking, that's OK too as long as the end user
understands that. I made a few observations in the code below
indicating the way I like to do some things, although I don't
always follow my own rules.

The routine collects LINE objects that the user selects and
then returns those with the LAYER set to Continuous. It does not
return lines set to Continuous with a layer set to a line type
other than Continuous. Is that your intention?
Code: [Select]
(defun c:gtl ()
  (prompt "\nSelect continuous ltype lines to filter ")
  (setq 1ss (ssget '((0 . "Line"))))
  ;;  if the user presses enter with nothing
  ;;  selected (sslength nil) fails
  (setq lss (sslength 1ss))
  (setq ssgrp (ssadd))
  (setq cntr 0)
  (while (< cntr lss)
    ;;  next line gets the entity list not the entity name
    ;;  perhaps entlst would be better than entnam
    (setq entnam (entget (ssname 1ss cntr)))
    (setq ln (cdr (assoc 8 entnam)))
    ;;  eval is not needed and you could combine the next 2 lines
    ;;(setq ssnam (cdr (assoc 6 (tblsearch "Layer" (eval ln)))))
    ;;(if (= ssnam "Continuous")
    ;;  resulting in the line below, eleminates the var ssnam
    (if (= (cdr (assoc 6 (tblsearch "Layer" ln))) "Continuous")
      ;;  you can eleminate the progn by combining the setq's
      ;;(progn
      ;;  (setq entnam (cdr (assoc -1 entnam)))
      ;;  (setq ssgrp (ssadd entnam ssgrp))
      ;;)
      ;;  like this
      (setq entnam (cdr (assoc -1 entnam))
            ssgrp  (ssadd entnam ssgrp)
      )

    )
    (setq cntr (1+ cntr))
  )
  (prompt " \n To access filtered selection set: <!ssgrp> ")
  (princ)
)
;;  you may want to tell the user how to run the routine
(prompt " \nLine Grabber Loaded, Enter gtl to run.")
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
easy filter
« Reply #18 on: July 14, 2004, 08:17:52 AM »
Rude dog,
There isn't much to butcher in your code. If you only intend to select entities on layers with linetype "Continuous", regardless of the object linetype, then it works perfectly.

A few notes, though:
The routine crashes if the user doesn't make a valid selection. Wrapping the whole thing in a condition will avoid that situation.

There's no need to use EVAL when searching the layer table. Evaluating a string has no real meaning.

SSADD manipulates the selection set directly so you only have use for its return value when creating a new sset, not when adding entities to it. Using SETQ only adds to the heat.

Instead of creating an additional selection set, you can also remove from an existing one with SSDEL. It works the same way as SSADD does. However, it requires a sligthly different construct of the loop because you can't fiddle with the length of the selection set and keep incrementing the counter at the same time.

This is how the same routine might be written using SSDEL:

Code: [Select]
(defun c:gtl (/ cntr entnam ssnam Ln)
  (prompt "\nSelect continuous ltype lines to filter ")
  (cond ((setq ssgrp (ssget '((0 . "Line"))))
         ;; Don't go further if a selectionset isn't created
         ;; Work with one and only one selection set
         (setq cntr 0)
         (while (setq entnam (ssname ssgrp cntr))
           (setq Ln (cdr (assoc 8 (entget entnam))))
           (setq ssnam (cdr (assoc 6 (tblsearch "Layer" Ln))))
           ;; if layer ltype is not "Continuous"
           (if (/= ssnam "Continuous")
             ;; .. then remove entnam
             (ssdel entnam ssgrp)
             ;; .. else increment counter
             (setq cntr (1+ cntr))
           )
         )
         (princ "\n To access filtered selection set: <!ssgrp> ")
        )
  )
  (princ)
)


You may want to take a different approach, though. The code below collects all layers that have the linetype "Continuous" and applies them to an SSGET filter. It is shorter in the sense that a selection set is created immediately without the need to run through it afterwards.
It is divided into three functions: a layer table searcher, a selection set builder and a command to deliver a global selection set. With it you can simply call (gtl) during an editing command to get the selection, or you can use it as a command to create a global selection set. The advantage seen from a coding point of view is that the layer table searcher is reusable. Say you want to make a filter for colors; just change the condition and voilá, new tool. Or simply add additional arguments when needed.

By the way, it filters for entities with bylayer linetype, also. Just remove the '(6 . "Bylayer) if it shouldn't do that.

Code: [Select]
(defun getLtLayer (ltype / ltlayer ltfilter)
  (setq ltfilter "")
  (while (setq ltlayer (tblnext "LAYER" (not ltlayer)))
    (and (= (strcase ltype) (strcase (cdr (assoc 6 ltlayer))))
         (setq ltfilter (strcat (cdr (assoc 2 ltlayer)) "," ltfilter))
    )
  )
  ltfilter
)

(defun gtl (/ lyrfilter sset)
  (and (setq lyrfilter (getLtLayer "Continuous"))
       (princ "\nSelect continuous ltype lines to filter ")
       (setq sset (ssget
                (list '(0 . "LINE") (cons 8 lyrfilter) '(6 . "Bylayer"))
              )
       )
  )
  sset
)

(defun C:GTL ()
  (if (setq ssgrp (gtl))
    (princ "\n To access filtered selection set: <!ssgrp>")
    (princ "\n No luck this time, buddy")
  )
  (princ)
)

SMadsen

  • Guest
easy filter
« Reply #19 on: July 14, 2004, 08:18:17 AM »
Oops, didn't see you sneak in there, CAB

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #20 on: July 14, 2004, 08:37:11 AM »
Hey Stig,
Great examples, really like the last one, reusable code.

one question on ssadd, you said
Quote from: Stig
SSADD manipulates the selection set directly so you only have use for its
return value when creating a new sset, not when adding entities to it.
Using SETQ only adds to the heat.

Do you prefer using
Code: [Select]
setq ssgrp '()) to create a null list?

I always learn from your post, Thanks.
« Last Edit: July 05, 2010, 10:37:06 AM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
easy filter
« Reply #21 on: July 14, 2004, 09:00:57 AM »
Quote from: CAB
Do you prefer using
Code: [Select]
setq ssgrp '()) to create a null list?

Ummm, not sure what you mean.

(setq ssgrp (ssadd))
will create an empty selection set and assign it to ssgrp but,

(ssadd some_entity ssgrp)
will modify ssgrp without the need to grab the return value. With SSADD it doesn't really matter if you grab the return value - other than it's redundant - but with SSDEL you will risk loosing the entire selection set. E.g.:

(setq sset (ssget))
(if (setq ent (entsel "\nPick an object to remove: "))
..(setq sset (ssdel (car ent) sset))

If ent is not part of sset then SSDEL will return nil and you'll loose the selection set. So, getting into the habit of using either of the two without SETQ is a good thing.

Added: on second thought, I do think it matters with SSADD knowing that there are only so many sset slots available and using SETQ will probably create a copy? Dunno. Haven't tested it.

Anonymous

  • Guest
easy filter
« Reply #22 on: July 14, 2004, 09:16:10 AM »
fantastic comments and examples thanks :!:  :!:
Quote

The routine collects LINE objects that the user selects and
then returns those with the LAYER set to Continuous. It does not
return lines set to Continuous with a layer set to a line type
other than Continuous. Is that your intention?

Cab, I was trying not not admitt this but the whole bylayer thing kinda confuses me :oops:
I just wanted the program to filter out lines that have a continuous linetype....just like if we opened a new session of autocad and drew a line with layer "0" set current and changed nothing....these are the type of lines I was after....I never have changed a lines linetype that comes default with its color.....
way to break it down in steps stig for later use....you da man
thanks for everyones time.....!

rude dog

  • Guest
easy filter
« Reply #23 on: July 14, 2004, 09:17:53 AM »
:oops:
that be me again

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #24 on: July 14, 2004, 09:42:15 AM »
Quote from: SMadsen
Quote from: CAB
Do you prefer using
Code: [Select]
setq ssgrp '()) to create a null list?

Ummm, not sure what you mean.


My mistake, I thought you were refering to
Code: [Select]
(setq ssgrp (ssadd ))
but you were actuall talking about
Code: [Select]
(setq ssgrp (ssadd entnam ssgrp))

Still good info on ssdel, I'm glad I asked. Didn't know that.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
easy filter
« Reply #25 on: July 14, 2004, 10:30:38 AM »
rude dog
the ByLayer thing is a way to control line type on a layer basis. Usually the Layer
line type is set to 'Continuous' and any line you draw on that layer is continuous.
The actual line has ByLayer as a line type so the LAYER controls the line type.
Say you have a layer called 'Medium Dashed' and you set the line weight to 'Medium'
which is controlled by your plot style stb file. I have a plot style called 'Arch D'
so lines weight for 'Medium' in that plot style is 0.30 so the line will plot at 0.30
when using that plot style.
In my LAYER 'Medium Dashed' the line type is set to 'DASHED'. When the line type of the
entity is ByLayer the LAYER line type controls the line type. The object will have a
DASHED line type applied to it. I can override the DASHED line type by changing the
objects line type to 'Continuous' instead of 'ByLayer' to get a continuous line.

I use this when I have a layer like 'Ceiling Details' and the line type is set to
'Short Dash'. All my lines on that layer have a Short Dash. On occasion I need to
differentiate a detail so I'll change that line type to 'Very Short Dash' or something
else besides 'Short Dash'.

Not sure if this helped or hurt. But the bottom line, pun intended, is the line with
'Continuous' in the linetype will have a continuous line displayed AND a line with
ByLayer' in the linetype and the Layer has 'Continuous' in the linetype will also have
a continuous line displayed. So if you want a selection set that contains lines that
"Display" a continuous line on the screen, you have to filter for both.

Stigs' filter:
Code: [Select]
(ssget '((0 . "LINE")(6 . "Continuous,Bylayer")))
will get the two types of lines and all you have to do is test the ByLayer group to see if
any layers have Continuous as a line type. Stigs last code example showed us yet another
way to do this.

I'm done.  :shock:
 CAB
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.