re-order selection set in distance of origin point

re-order selection set in distance of origin point

alique.langlois
Enthusiast Enthusiast
1,389 Views
6 Replies
Message 1 of 7

re-order selection set in distance of origin point

alique.langlois
Enthusiast
Enthusiast

I need an outside perspective and some wisdom too.

 

I had set up a selection set and need to order it closest to the farthest object (blocks) once done. I will be generating information to load into the attribute of those blocks.

 

I have the code to put the data into the blocks and code to select the selection set (ss).  I just can't get the code to organize the ss to work. When I do, it breaks the entity information and I can't load the attribute into the blocks.

 

what I found  searching around brought me this old post: https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/selection-set-re-sort/td-p/871586 

I can't make heads or tails of the code. Not sure how it works, but it looks very close to what I need.

 

Data in : my filtered ss

Data out : ss in order of closes to my origin point I selected. So I can pull the entity list with Lee Mac's selection set to list script. And load my blocks with the right information.

 

This is how I did it:

(setq tempss 
		(ssget "_C" pt1 pt2 
				'((0 . "INSERT") (2 . "*Tracker"))
		);ssget
		i 0
	);setq
	;do on all blockselect
	(while (and tempss (< i (sslength tempss)))
		(setq ent (entget (ssname tempss i))
		
	; make a list of entities with the distance from first point
			px (dxf 10 ent)
			dist (distance pt1 px)


			
			CLIST (append CLIST
					(list
						(list dist (car ent))
						) ;list
					);append
		); setq
;-----------------
;(print (car ent))
;-----------------		
		(setq i (1+ i))
	);while 
	
	(setq ben (LM:ss->ent tempss))
;-----------------
;(print CLIST)
;-----------------	
	;sort the list with closest to farthest
	(setq CLIST 
		(vl-sort
			CLIST 
				(function (lambda (a1 a2)
					(<	(car a1) (car a2))
				)) ;end of lambda
		) ;vl-sort
	);setq
;-----------------

 

 

 

0 Likes
Accepted solutions (2)
1,390 Views
6 Replies
Replies (6)
Message 2 of 7

Sea-Haven
Mentor
Mentor
Accepted solution

My test of your code

 

(setq pt1 (getpoint))
(setq pt2 (getpoint))
(setq tempss (ssget "_C" pt1 pt2 '((0 . "INSERT") (2 . "Northn")) ))
(if (/= tempss nil)
(progn
(setq clist '())
(repeat (setq i (sslength tempss))
		(setq ent (entget (ssname tempss (setq i (- i 1))))
		px (cdr (assoc 10 ent))
		dist (distance pt1 px)
		CLIST (cons (list dist (cdr (assoc -1 ent))) clist ))
)
)
)

(setq CLIST 
		(vl-sort
			CLIST 
				(lambda (a1 a2)
					(<	(car a1) (car a2))
				)
		)
)

(command "erase" (cadr (nth 1 clist))) this will demonstrate that it finds a block and erases it.

0 Likes
Message 3 of 7

alique.langlois
Enthusiast
Enthusiast

Thank you @Sea-Haven  Once again! I still have some syntax to learn. 

 

I had found an old post by @Kent1Cooper  that had a really good lisp he called BlockSSSort.lsp that I was going to use. It would have been overkill for what I need right now but it has the potential for the future. 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/assigning-attributes-to-blocks-using...

0 Likes
Message 4 of 7

ВeekeeCZ
Consultant
Consultant
Accepted solution

There are 3 things in @Sea-Haven that worts to point out and which I would use the same.

 

1) always test user inputs

2) there are many ways how to go through a selection set. Lee has this nicely done HERE even with some commentaries and pros/cons. I would also recommend using the 2a method - all the indexing stuff is part of the loop and at located at the beginning... so you won't forget about that. Also, it's very efficient.

3) When building a list, the simpler and the most effective way is using a cons function. (setq lst (cons itm lst)). The order of itm-lst matters, it won't work the other way around! One of the cons is that it builds the list in reversed order - it usually does not matter, or just use (reverse lst) if that's an issue.

 

So my version... very similar to @Sea-Haven 's 

(if (and (setq pt1 (getpoint))			
	 (setq pt2 (getpoint))
	 (setq tempss (ssget "_C" pt1 pt2 '((0 . "INSERT") (2 . "Northn"))))
	 )

  (repeat (setq i (sslength tempss))
    (setq ent (ssname tempss (setq i (- i 1))))

    (setq ptx (cdr (assoc 10 (entget ent)))
	  dst (distance pt1 ptx)
	  lst (cons (cons dst ent) lst))))

(setq lst (vl-sort lst (lambda (a1 a2) (< (car a1) (car a2)))))

Have fun!

0 Likes
Message 5 of 7

alique.langlois
Enthusiast
Enthusiast

Hello @ВeekeeCZ ,

 

This just lit up the light bulb with that explanation. Thank you. I had found the info on Lee Mac's site (it become a point of reference), but I didn't put enough time to really understand. 

What I would like to know so I can better understand is the point that destroyed the entity name in my code, or was it many points. 

 

Thanks in advance if you can. Not to worry if you are helping others. 😀

0 Likes
Message 6 of 7

ВeekeeCZ
Consultant
Consultant

@alique.langlois wrote:

Hello @ВeekeeCZ ,

 

What I would like to know so I can better understand is the point that destroyed the entity name in my code, or was it many points. 

😀


 

;; your...
(setq ent (entget * (ssname tempss i))   ;; ent stores an entity definition list. here * you skipped ename!!
      px (dxf 10 ent)			;; this is OK
      ...
       (list dist (car ent)) 		;; this is very bad - only usage of (car ent) is from (entsel)... because (entsel) returns: '(ename . point)
      					;; But your ent stores whole list ((-1 . <Entity name: 432c9ef0>) (0 . "ARC") ...)
      					;; in your case that shoudl be (list dist (cdr (assoc -1 ent)))    or    using the dxf sub: (list dist (dxf -1 ent))


;; better is 

      (setq ent (ssname tempss i))   	;; ent stores ename
            edl (entget ent)		;; edl stores entity def. list
       
      px (dxf 10 edl)			
      ...
       (list dist ent) 			


   ;; or just as I did...

       (setq ent (ssname tempss i)
	     px  (cdr (assoc 10 (entget ent)))  ;; I prefer to NOT use the dxf sub
	     ...
	      (list dist ent))

 

0 Likes
Message 7 of 7

alique.langlois
Enthusiast
Enthusiast

Thank you! I just had another road of Aha moment with a soundtrack of "I can see clearly now" in the background! 😋

 

@ВeekeeCZ  I am truly grateful for the time you took.