LISP block sorting routine (by insertion coordinate)

LISP block sorting routine (by insertion coordinate)

kyle_dean
Participant Participant
1,995 Views
12 Replies
Message 1 of 13

LISP block sorting routine (by insertion coordinate)

kyle_dean
Participant
Participant

Hello,

 

I am trying to write a function that will get a selection of blocks, and then return a list of the blocks sorted by insertion x,y (left to right, top to bottom). 

 

 

 

 

(defun c:exp1 (/ ss i lst en)
 (if (setq ss (ssget))
   (progn (repeat (setq i (sslength ss))
    (setq en (ssname ss (setq i (1- i)))
     lst (cons (cons en (cdr (assoc 10 (entget en)))) lst))
     )
    (setq s_lst (vl-sort lst '(lambda (x y) (if (= (car x) (car y)) (> (cadr x) (cadr y)) (< (car x) (car y)))))) 
   )
   
   )
 (princ)
 )

 

 I'm trying to make it so that s_lst is the final sorted list. When I run the script it returns error "bad argument type for compare: <Entity name: 1fa972769b0> <Entity name: 1fa97276a90>". I think it must have something to do with the lambda sorting function but I'm not sure.

 

I have done some searching and i'm getting pretty close close (I can sort by X coordinate only). See below for working X-coordinate sort.

(defun c:exp1 (/ ss i lst en)
 (if (setq ss (ssget))
   (progn (repeat (setq i (sslength ss))
    (setq en (ssname ss (setq i (1- i)))
     lst (cons (cons en (cdr (assoc 10 (entget en)))) lst))
     )
     (mapcar 'print (vl-sort lst ''((a b) (< (cadr a) (cadr b)))))
     )
    
   
   )
 (princ)
 )

 

Thanks,

0 Likes
Accepted solutions (1)
1,996 Views
12 Replies
Replies (12)
Message 2 of 13

Kent1Cooper
Consultant
Consultant

I think BlockSSSort.lsp should be able to do what you want -- available >here<.  [Note that it defines not a command, but a function with arguments -- for what you describe, put in at the command line  (BSSS "T" "L") .]

Kent Cooper, AIA
0 Likes
Message 3 of 13

jtohill
Advocate
Advocate

I use the data extraction tools and use a table to do the work for me.

0 Likes
Message 4 of 13

ВeekeeCZ
Consultant
Consultant

(cons (cons en pt) lst) will create a list of (e x y z)'s. So then you need (caddr) to sort by Y and (cadr) to sort by X. You are one d short.

 

(defun c:exp1 (/ ss i lst en)
  (if (setq ss (ssget))
    (progn
      (repeat (setq i (sslength ss))
	(setq en (ssname ss (setq i (1- i)))
	      lst (cons (cons en (cdr (assoc 10 (entget en)))) lst)))
      (setq s_lst (vl-sort lst '(lambda (a b) (< (caddr a) (caddr b))))
	    s_lst (vl-sort s_lst '(lambda (a b) (< (cadr a) (cadr b)))))
      (print s_lst)))
  (princ)
  )

 

0 Likes
Message 5 of 13

kyle_dean
Participant
Participant

@Kent1Cooper 

 

Thanks for the reply. I downloaded the .lsp and loaded it, but the command returns the following error when i run (BSSS "T" "L"):

bad argument type: consp <Entity name: 19222e22ef0>

 

Any advice? Because it definitely looks like that code is exactly what I need.

0 Likes
Message 6 of 13

kyle_dean
Participant
Participant
Accepted solution

Thank you very much @ВeekeeCZ This works for me now. I had to modify the code a little bit to make it sort in the order I wanted but the following works now:

 

(defun c:bsort (/ ss i lst en)
  (if (setq ss (ssget))
    (progn
      (repeat (setq i (sslength ss))
	(setq en (ssname ss (setq i (1- i)))
	      lst (cons (cons en (cdr (assoc 10 (entget en)))) lst)))
      (setq s_lst (vl-sort lst '(lambda (a b) (< (cadr a) (cadr b))))
	    s_lst (vl-sort s_lst '(lambda (a b) (< (caddr b) (caddr a)))))
      )
    )
)

 

Basically I just had to flip the order of the sorts around a little to make it go left to right then top to bottom

 

0 Likes
Message 7 of 13

Kent1Cooper
Consultant
Consultant

@kyle_dean wrote:

....

bad argument type: consp <Entity name: 19222e22ef0>

....


I'm not sure what that could be.  It works for me the first time, but running it again gives the same error.  I'll have to dig into it tomorrow....

Kent Cooper, AIA
0 Likes
Message 8 of 13

cadffm
Consultant
Consultant

Time booster 4U

 

Argumenttyp: consp

 

Something is expecting a list - but there isn't. In this case it is function 'cadr' in the last codeline.

Issue: blsort2 is not set as local variable

Solution, add blsort2 to the list of local variables (and offtopic, I would skip the last unnecessary symbol bind)

Sebastian

0 Likes
Message 9 of 13

Sea-Haven
Mentor
Mentor

Just a suggestion 

(setq ss (ssget))

 

This can get all sorts of objects as there is no filters to say pick block only

(setq ss (ssget '((0 . "INSERT"))))

If you want multiple blocks then you could pre process say pick blocks Block1 block2 so ssget is now 

(setq ss (ssget (list (cons 0 "INSERT")(cons 2 blkstr))))

blkstr is "Block1,Block2"

 

 

0 Likes
Message 10 of 13

Kent1Cooper
Consultant
Consultant

@cadffm wrote:

....

Solution, add blsort2 to the list of local variables (and offtopic, I would skip the last unnecessary symbol bind)


No in both cases.  It is deliberately bound at the end and not localized, so that you can make use of it afterwards.  The attached explicitly sets it to nil at the front, in case there's one remaining from a prior use, which takes care of it.

Kent Cooper, AIA
0 Likes
Message 11 of 13

kyle_dean
Participant
Participant

@Sea-Haven Thanks for the tip. I'm still pretty new to LISP so I'm still trying to understand pretty fundamental concepts. Is it possible to use that formatting of the ssget to filter a selection set of objects by layer? Say I draw a selection area in autocad that grabs a lot of objects that i don't want and only want to continue with a list of the selected blocks that are on a certain layer.

 

Thanks again.

-Kyle

0 Likes
Message 12 of 13

Kent1Cooper
Consultant
Consultant

@kyle_dean wrote:

.... Say I draw a selection area in autocad that grabs a lot of objects that i don't want and only want to continue with a list of the selected blocks that are on a certain layer. ....


Add the Layer entry to the (ssget) filter list.  That's the DXF-code 8 entry:

(setq ss (ssget '((0 . "INSERT") (8 . "YourLayerName"))))

Read more about (ssget) in the AutoLisp Reference >here<, and about the DXF code numbers for the various pieces of data about various entity types >here<.

Kent Cooper, AIA
0 Likes
Message 13 of 13

kyle_dean
Participant
Participant

@Kent1Cooper  Yall are amazing. Thanks for your reply. I hope to achieve guru level knowledge of Auto Lisp like you all one day!

0 Likes