Author Topic: How to filter subEntities in block  (Read 717 times)

0 Members and 1 Guest are viewing this topic.

xinxirong

  • Mosquito
  • Posts: 17
How to filter subEntities in block
« on: March 22, 2017, 11:24:40 PM »
Well known that (ssget filter-list) only support entities in model(paper) space.If i has a list of ename ,or a entity in block,how can i judge it matching the specified criteria (filter-list)?
the filter-list maybe :
1.Wild-Card Patterns in Filter Lists
2.Relational operators for selection set filter lists
3.Logical Grouping of Filter Tests

and i want to make it as function.

(defun determin_ename (ent filter / )
  ;return t if ent matching the specified criteria
)

Master_Shake

  • Swamp Rat
  • Posts: 1447
Re: How to filter subEntities in block
« Reply #1 on: March 23, 2017, 08:16:37 AM »
I don't follow, can you layout an example?

Maybe you are asking how to filter a certain block name?

Code - Auto/Visual Lisp: [Select]
  1. '((0 . "INSERT")(2 . "Block"))

xinxirong

  • Mosquito
  • Posts: 17
Re: How to filter subEntities in block
« Reply #2 on: March 23, 2017, 09:17:59 AM »
find text in block which height >200,wide factor <0.8 or =1,string match "*searchString*"

Code: [Select]
(setq ent (car (nentsel));40 text height,41 wide factor
      filter '((0 . "TEXT")
       (1 . "*searchString*")
       (-4 . "<AND")
       (-4 . ">=")
       (40 . 200)
       (-4 . "<OR")
       (-4 . "<")
       (41 . 0.8)
       (-4 . "=")
       (41 . 1.0)
       (-4 . "OR>")
       (-4 . "AND>")
       )
      )
;test ssget Success
(setq ss (ssget filter))

(if (determin_ename ent filter)
  (princ "the entity you nentsel match")
  ;else
  (princ "the entity you nentsel not match")
  )

Lee Mac

  • Seagull
  • Posts: 12284
  • London, England
Re: How to filter subEntities in block
« Reply #3 on: March 23, 2017, 09:26:43 AM »
You will need to iterate over the objects/entities found within the block definition and test the Properties/DXF data to determine a match. This can be achieved either using vlax-for to iterate over the vla-objects contained within the definition obtained from the Blocks Collection, or by using entnext to iterate over the entities following the entity returned by the tblobjname function.

xinxirong

  • Mosquito
  • Posts: 17
Re: How to filter subEntities in block
« Reply #4 on: March 23, 2017, 08:40:28 PM »
the hardest part is  function determin_ename,
1、Wild-Card Patterns ,i can use wcmatch
2、Relational operators for selection set filter lists ,
3、Logical Grouping of Filter Tests
2&3 ,something like use lisp to dealwith lisp
"*"   Anything goes (always true)
"="   Equals
"!="   Not equal to
"/="   Not equal to
"<>"   Not equal to
"<"   Less than
"<=" Less than or equal to
">" Greater than
">=" Greater than or equal to
"&" Bitwise AND (integer groups only)
"&=" Bitwise masked equals (integer groups only)

"<AND"    "AND>"      One or more operands
"<OR"  "OR>"      One or more operands
"<XOR" "XOR>"      Two operands
"<NOT" "NOT>"      One operand

Grrr1337

  • Swamp Rat
  • Posts: 708
Re: How to filter subEntities in block
« Reply #5 on: March 24, 2017, 10:49:46 AM »

Just like Lee said - iterate over the enames/objects inside the block definition.
Additionally use subfunction that expects a test function argument, to filter in/out the required objects.

Code - Auto/Visual Lisp: [Select]
  1. ; (foo (lambda (e) (= "CIRCLE" (cdr (assoc 0 (entget e))))) (car (entsel)))
  2. ; (foo (lambda (e / enx) (and (setq enx (entget e)) (/= "0" (cdr (assoc 8 enx))) (= "CIRCLE" (cdr (assoc 0 enx))))) (car (entsel)))
  3. (defun foo ( f b / L )
  4.   (and
  5.     (or (and (eq 'STR (type b)) (tblsearch "BLOCK" b) (setq b (tblobjname "BLOCK" b)) )
  6.       (setq b
  7.         (tblobjname "BLOCK"
  8.           (cond
  9.             ( (eq 'ENAME (type b)) (vla-get-EffectiveName (vlax-ename->vla-object b)) )
  10.             ( (eq 'VLA-OBJECT (type b)) (vla-get-EffectiveName b) )
  11.             ( "" )
  12.           ); cond  
  13.         )
  14.       ); setq
  15.       (setq b nil)
  16.     ); or
  17.     (while (and (setq b (entnext b)) (/= "ENDBLK" (cdr (assoc 0 (entget b)))))
  18.       (if (f b) (setq L (cons b L)) )
  19.     ); while
  20.   ); and
  21.   (reverse L)
  22. ); defun foo
  23.  


SSget filter won't work unless theres a way to filter implied selection, that collected the enames inside.
The following probably won't work, just writing in theory:

Code - Auto/Visual Lisp: [Select]
  1. ; (foo "asd" '((0 . "CIRCLE")))
  2. (defun foo ( b ftl / SS SSn )
  3.   (and
  4.     (tblsearch "BLOCK" b)
  5.     (setq b (tblobjname "BLOCK" b))
  6.     (sssetfirst nil nil)
  7.     (setq SS (ssadd))
  8.     (progn
  9.       (while (and (setq b (entnext b)) (/= "ENDBLK" (cdr (assoc 0 (entget b)))))
  10.         (ssadd b SS)
  11.       ); while
  12.       (sssetfirst nil SS)
  13.       (setq SSn (ssget "_I" ftl))
  14.     ); progn
  15.   ); and
  16.   SSn
  17. ); defun foo [code]
  18.  
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)