Author Topic: Sort list help  (Read 1731 times)

0 Members and 1 Guest are viewing this topic.

CincyJeff

  • Newt
  • Posts: 89
Sort list help
« on: November 13, 2015, 10:26:00 AM »
I'm having trouble sorting an entity list by insertion point y-value. We have rows of blocks that are typically separated by 20' or so but sometimes adjacent rows can only be a few feet different in y-value. Within each row the blocks can have y-values that can differ by as much as 1'. I have a list of entities that I want to sort so that all similar y-values (within a 12" fuzz factor) are placed into a separate list from largest to smallest. The final list would look something like: ((ent1 ent3 ent4) (ent2 ent5 ent6) (ent7 ent8)). Entities 3 & 4 would have insertion points within 12" of entity 1. The entity 2 insertion point would be further than 12" from entity 1 and entities 5 & 6 would have insertion points within 12" of entity 2, and so on. The first instance of any block that has an insertion point greater than 12" from a previous value can be used as a new base for comparison. Each sublist would represent a row of blocks that have insertion points with y-values within 12" of each other. The posted code will create the entity list for the attached example drawing. The example should produce a list of 4 sublists.

blk:l - (ent1 ent2 ent3 ...)
yval:l - ((ent1 ent3 ent4) (ent2 ent5 ent6) (ent7 ent8))

take first item in blk:l
get y-val & put in yval:l
take next item in blk:l
get y-val & compare to yval:l
 if within 12" of any first subitem in yval:l (in list above only compare to ent1 ent2 ent7)
  add to subitem
  else create new subitem

Code - Auto/Visual Lisp: [Select]
  1. (defun C:SORTTEST (/ pt1 pt2 selset)
  2.   (setq pt1    (getpoint "\nSelect blocks to sort ")
  3.         pt2    (getcorner pt1 "\nOther corner ")
  4.         selset (ssget "_W"
  5.                       pt1
  6.                       pt2
  7.                       '((0 . "INSERT") (2 . "test"))
  8.                ) ;_ end of ssget
  9.         blk:l  (UTIL:SELSET->LIST selset nil)
  10.   ) ;_ end of setq
  11. ;; sort list sort:l here
  12. ) ;_ end of defun
  13.  
  14. (defun UTIL:SELSET->LIST (selset entorobj / cnt sslist)
  15.   (setq cnt 0)
  16.   (repeat (sslength selset)
  17.     (setq sslist (cons (ssname selset cnt) sslist))
  18.     (setq cnt (1+ cnt))
  19.   ) ;_ end of repeat
  20.   (if (= "OBJECT" entorobj)
  21.     (setq sslist (mapcar 'vlax-ename->vla-object sslist))
  22.   ) ;_ end of if
  23.   sslist
  24. )


ronjonp

  • Needs a day job
  • Posts: 7531
Re: Sort list help
« Reply #1 on: November 13, 2015, 11:08:29 AM »
Maybe this will give you some ideas.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ _dxf b n out ss tmp y)
  2.   (defun _dxf (c e) (cdr (assoc c (entget e))))
  3.   (if ;; If we have a selection set of blocks
  4.       (setq ss (ssget "_X" '((0 . "insert"))))
  5.     (progn ;; Convert selection set to list of enames & sort by smallest Y value
  6.       (setq ss (vl-sort (mapcar 'cadr (ssnamex ss))
  7.               '(lambda (a b) (> (cadr (_dxf 10 a)) (cadr (_dxf 10 b))))
  8.           )
  9.       )
  10.       (while (car ss)
  11.         ;; Get Y value
  12.         (setq y (cadr (_dxf 10 (car ss))))
  13.         ;; Grab all other blocks with same Y within a fuzz of 12 while sorting by smallest X value
  14.         (setq tmp (vl-sort   (vl-remove-if-not '(lambda (x) (equal y (cadr (_dxf 10 x)) 12)) ss)
  15.             '(lambda (a b) (< (car (_dxf 10 a)) (car (_dxf 10 b))))
  16.              )
  17.         )
  18.         ;; Put items in list 'out'
  19.         (setq out (cons tmp out))
  20.         ;; Remove from list 'ss' we're iterating
  21.         (foreach tm tmp (setq ss (vl-remove tm ss)))
  22.       )
  23.     )
  24.   )
  25.   ;; Result
  26.   out
  27. )


You can also directly filter by an insertion point like so ( example does Y ):
Code - Auto/Visual Lisp: [Select]
  1. (defun bby (point fuzz)
  2.     nil
  3.     (ssget "_X"
  4.            (list '(0 . "insert")
  5.                  '(-4 . "<AND")
  6.                  '(-4 . "*,>=")
  7.                  (cons 10 (list (car point) (- (cadr point) fuzz)))
  8.                  '(-4 . "*,<=")
  9.                  (cons 10 (list (car point) (+ (cadr point) fuzz)))
  10.                  '(-4 . "AND>")
  11.            )
  12.     )
  13.   )
  14. )
  15. (bby (trans (getpoint) 1 0) 12.)
« Last Edit: November 13, 2015, 12:14:04 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CincyJeff

  • Newt
  • Posts: 89
Re: Sort list help
« Reply #2 on: November 13, 2015, 12:44:47 PM »
Thanks ronjonp, with a few tweaks that works for me. I appreciate the help. BTW, I did not realize you could filter the insertion point like that. Good to no and thanks again.

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Sort list help
« Reply #3 on: November 13, 2015, 01:26:03 PM »
Thanks ronjonp, with a few tweaks that works for me. I appreciate the help. BTW, I did not realize you could filter the insertion point like that. Good to no and thanks again.


Glad to help :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC