Selection set re-sort

Selection set re-sort

Anonymous
Not applicable
372 Views
5 Replies
Message 1 of 6

Selection set re-sort

Anonymous
Not applicable
Does any body have a LISP routine that will take a selection set and re-sort
it in order of x,y coordinates.

Dan
A2K
0 Likes
373 Views
5 Replies
Replies (5)
Message 2 of 6

Anonymous
Not applicable
Dan - Assuming you want to sort on the y-ordinate of
each text object, and all of them are left-aligned,
this will do it:

The code below will allow you to sort a selection of
text on a given key (in the example shown below, it
is the Y-ordinate of each insertion point).

If you want to physically rearrange the order of the
text in the drawing, this will get you part of the way
there.

;; SSINDEX.LSP Copyright 2000 Tony Tanzillo all rights reserved
;;
;; This material may not be reproduced or redistributed
;; without the expressed written consent of the author.
;;
;; (list-index )
;;
;; Sorts and returns a list of
;; integers representing the indices of the
;; elements in in their sorted order,
;; as defined by , a function that
;; takes two elements and returns a value
;; whose logical interpretation indicates the
;; relationship between the two values.

(defun list-index (input func / i)
(setq i -1)
(mapcar 'cdr
(vl-sort
(mapcar
'(lambda (val)
(cons val (setq i (1+ i)))
)
input
)
'(lambda (a b)
(apply func (mapcar 'car (list a b)))
)
)
)
)

;; (ss-index )
;;
;; where:
;;
;; (if (
;; ( )
;; ( )
;; )
;; <<< is less than >>>
;; <<< is less than >>>
;; )
;;
;; Returns a list of integers representing the
;; indices of the elements in the selection set
;; in the sorted order, where the function
;; takes each entity name in the selection set, and
;; returns that entity's sort key, and
;; takes the sort keys of two entities, and returns
;; a value whose logical interpretation indicates
;; the relationship of the two keys.

(defun ss-index (ss _getKey _compareKey / keylist i)
(repeat (setq i (sslength ss))
(setq keylist
(cons
(apply _getKey (list (ssname ss (setq i (1- i)))))
keylist
)
)
)
(list-index keylist _compareKey)
)

;; Test SS-INDEX. Prompts for a selection set of text,
;; and appends an integer to each text's value string,
;; which is the index of the text in the sorted order.

(defun C:TEST ( / ss indices oldtext)
(setq ss (ssget '((0 . "TEXT"))))
(setq indices
(ss-index ss
'(lambda (ename)
(caddr (assoc 10 (entget ename))) ;; sort key = Y-ordinate
)
'> ;; sort comparison function = < (is-greater-than)
)
)
(setq j -1)
(foreach i indices
(setq e (ssname ss i))
(setq oldtext (cdr (assoc 1 (entget e))))
(entmod
(list
(cons -1 e)
(cons 1
(strcat
oldtext
" ( "
(itoa (setq j (1+ j)))
" ) "
)
)
)
)
)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SSINDEX.LSP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dane wrote:
>
> A selection set of text objects is what I'm trying to sort.
>
> Dan

--
/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://ourworld.compuserve.com/homepages/tonyt */
/*********************************************************/
0 Likes
Message 3 of 6

Anonymous
Not applicable
Apparently, Frank does not understand how to do multiple-
key sorting. The code he posted does not sort on the X and
Y ordinate of any point.

Rather, it merely sorts on the distance from the specified
point to the lower-left corner of the extents box containing
all of the text in the selection set, which I'm sure is not
what you meant by "in order of on X,Y coordinates". 🙂

The code I posted is designed to allow you to define how
the sort works, and what key(s) are used. Using it to sort
on the X and Y of a point is very easy to do.

This example uses the same functions from my prior post,
except that it sorts the left-aligned text first on the
X, and then on the Y component of each insertion point:

(setq epsilon 1.0e-6)

;; Using this as the comparison function passed
;; to (ss-index) will sort the text first on Y
;; component of the insertion poing, and then on
;; the X component of same:

(defun compare-points (p1 p2)
(if (equal (cadr p1) (cadr p2) epsilon)
(< (car p1) (car p2))
(< (cadr p1) (cadr p2))
)
)

(defun C:TEST ( / ss indices oldtext)
(setq ss (ssget '((0 . "TEXT"))))
(setq indices
(ss-index ss
'(lambda (ename)
(cdr (assoc 10 (entget ename))) ;; cache entire point
) ;; as sort key
'compare-points ;; comparison function
)
)
(setq j -1)
(foreach i indices
(setq e (ssname ss i))
(setq oldtext (cdr (assoc 1 (entget e))))
(entmod
(list
(cons -1 e)
(cons 1
(strcat
oldtext
" ( "
(itoa (setq j (1+ j)))
" ) "
)
)
)
)
)
)

Dan Elkins wrote:
>
> Does any body have a LISP routine that will take a selection set and re-sort
> it in order of x,y coordinates.
>
> Dan
> A2K

--
/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://ourworld.compuserve.com/homepages/tonyt */
/*********************************************************/
0 Likes
Message 4 of 6

Anonymous
Not applicable
Tony,

I tried your program on a selection of text entities and it returned a "null
function". Now I am just a LISP hacker and maybe I dont understand the program
completly. The program as I understand it, goes thru each of the text entities in
the selection and adds a number that is equals the sorted order. ( i hope that
made sense). Any help would be appreciated!

Thanks,

Paul

Tony Tanzillo wrote:

> Apparently, Frank does not understand how to do multiple-
> key sorting. The code he posted does not sort on the X and
> Y ordinate of any point.
>
> Rather, it merely sorts on the distance from the specified
> point to the lower-left corner of the extents box containing
> all of the text in the selection set, which I'm sure is not
> what you meant by "in order of on X,Y coordinates". 🙂
>
> The code I posted is designed to allow you to define how
> the sort works, and what key(s) are used. Using it to sort
> on the X and Y of a point is very easy to do.
>
> This example uses the same functions from my prior post,
> except that it sorts the left-aligned text first on the
> X, and then on the Y component of each insertion point:
>
> (setq epsilon 1.0e-6)
>
> ;; Using this as the comparison function passed
> ;; to (ss-index) will sort the text first on Y
> ;; component of the insertion poing, and then on
> ;; the X component of same:
>
> (defun compare-points (p1 p2)
> (if (equal (cadr p1) (cadr p2) epsilon)
> (< (car p1) (car p2))
> (< (cadr p1) (cadr p2))
> )
> )
>
> (defun C:TEST ( / ss indices oldtext)
> (setq ss (ssget '((0 . "TEXT"))))
> (setq indices
> (ss-index ss
> '(lambda (ename)
> (cdr (assoc 10 (entget ename))) ;; cache entire point
> ) ;; as sort key
> 'compare-points ;; comparison function
> )
> )
> (setq j -1)
> (foreach i indices
> (setq e (ssname ss i))
> (setq oldtext (cdr (assoc 1 (entget e))))
> (entmod
> (list
> (cons -1 e)
> (cons 1
> (strcat
> oldtext
> " ( "
> (itoa (setq j (1+ j)))
> " ) "
> )
> )
> )
> )
> )
> )
>
> Dan Elkins wrote:
> >
> > Does any body have a LISP routine that will take a selection set and re-sort
> > it in order of x,y coordinates.
> >
> > Dan
> > A2K
>
> --
> /*********************************************************/
> /* Tony Tanzillo Design Automation Consulting */
> /* Programming & Customization for AutoCAD & Compatibles */
> /* ----------------------------------------------------- */
> /* tony.tanzillo@worldnet.att.net */
> /* http://ourworld.compuserve.com/homepages/tonyt */
> /*********************************************************/

--
Stock & Associates Consulting Engineers, Inc. reserves all copyright rights, but
grants a temporary license to the recipient to use the materials contained in the
attached computer data file for use in development of recipient's work associated
with this project. Stock & Associates Consulting Engineers, Inc. does not warrant
the accuracy of any information contained on said data file. Stock & Associates
Consulting Engineers, Inc. assumes no liability for unauthorized alterations and
alterations to the information contained herein.
0 Likes
Message 5 of 6

Anonymous
Not applicable
Apparently, Frank does not understand how to do multiple-
key sorting. The code he posted does not sort on the X and
Y ordinate of any point.

Rather, it merely sorts on the distance from the specified
point to the lower-left corner of the extents box containing
all of the text in the selection set, which I'm sure is not
what you meant by "in order of on X,Y coordinates". 🙂

The code I posted is designed to allow you to define how
the sort works, and what key(s) are used. Using it to sort
on the X and Y of a point is very easy to do.

This example uses the same functions from my prior post,
except that it sorts the left-aligned text on both the Y
and the X component of each insertion point, such that if
two or more text entities have insertion points with equal
Y values, they are then sorted by the X ordinates of their
insertion points.

(setq epsilon 1.0e-6)

;; Using this as the comparison function passed
;; to (ss-index) will sort the text first on Y
;; component of the insertion poing, and then on
;; the X component of same:

(defun compare-points (p1 p2)
(if (equal (cadr p1) (cadr p2) epsilon)
(< (car p1) (car p2))
(< (cadr p1) (cadr p2))
)
)

(defun C:TEST ( / ss indices oldtext)
(setq ss (ssget '((0 . "TEXT"))))
(setq indices
(ss-index ss
'(lambda (ename)
(cdr (assoc 10 (entget ename))) ;; cache entire point
) ;; as sort key
'compare-points ;; comparison function
)
)
(setq j -1)
(foreach i indices
(setq e (ssname ss i))
(setq oldtext (cdr (assoc 1 (entget e))))
(entmod
(list
(cons -1 e)
(cons 1
(strcat
oldtext
" ( "
(itoa (setq j (1+ j)))
" ) "
)
)
)
)
)
)

Dan Elkins wrote:
>
> Does any body have a LISP routine that will take a selection set and re-sort
> it in order of x,y coordinates.
>
> Dan
> A2K

--
/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://ourworld.compuserve.com/homepages/tonyt */
/*********************************************************/
0 Likes
Message 6 of 6

Anonymous
Not applicable
Paul - It works for me.

Perhaps you missed a few lines?

Paul Graf wrote:
>
> Tony,
>
> I tried your program on a selection of text entities and it returned a "null
> function". Now I am just a LISP hacker and maybe I dont understand the program
> completly. The program as I understand it, goes thru each of the text entities in
> the selection and adds a number that is equals the sorted order. ( i hope that
> made sense). Any help would be appreciated!
>
> Thanks,
>
> Paul
>
> Tony Tanzillo wrote:
>
> > Apparently, Frank does not understand how to do multiple-
> > key sorting. The code he posted does not sort on the X and
> > Y ordinate of any point.
> >
> > Rather, it merely sorts on the distance from the specified
> > point to the lower-left corner of the extents box containing
> > all of the text in the selection set, which I'm sure is not
> > what you meant by "in order of on X,Y coordinates". 🙂
> >
> > The code I posted is designed to allow you to define how
> > the sort works, and what key(s) are used. Using it to sort
> > on the X and Y of a point is very easy to do.
> >
> > This example uses the same functions from my prior post,
> > except that it sorts the left-aligned text first on the
> > X, and then on the Y component of each insertion point:
> >
> > (setq epsilon 1.0e-6)
> >
> > ;; Using this as the comparison function passed
> > ;; to (ss-index) will sort the text first on Y
> > ;; component of the insertion poing, and then on
> > ;; the X component of same:
> >
> > (defun compare-points (p1 p2)
> > (if (equal (cadr p1) (cadr p2) epsilon)
> > (< (car p1) (car p2))
> > (< (cadr p1) (cadr p2))
> > )
> > )
> >
> > (defun C:TEST ( / ss indices oldtext)
> > (setq ss (ssget '((0 . "TEXT"))))
> > (setq indices
> > (ss-index ss
> > '(lambda (ename)
> > (cdr (assoc 10 (entget ename))) ;; cache entire point
> > ) ;; as sort key
> > 'compare-points ;; comparison function
> > )
> > )
> > (setq j -1)
> > (foreach i indices
> > (setq e (ssname ss i))
> > (setq oldtext (cdr (assoc 1 (entget e))))
> > (entmod
> > (list
> > (cons -1 e)
> > (cons 1
> > (strcat
> > oldtext
> > " ( "
> > (itoa (setq j (1+ j)))
> > " ) "
> > )
> > )
> > )
> > )
> > )
> > )
> >
> > Dan Elkins wrote:
> > >
> > > Does any body have a LISP routine that will take a selection set and re-sort
> > > it in order of x,y coordinates.
> > >
> > > Dan
> > > A2K
> >
> > --
> > /*********************************************************/
> > /* Tony Tanzillo Design Automation Consulting */
> > /* Programming & Customization for AutoCAD & Compatibles */
> > /* ----------------------------------------------------- */
> > /* tony.tanzillo@worldnet.att.net */
> > /* http://ourworld.compuserve.com/homepages/tonyt */
> > /*********************************************************/
>
> --
> Stock & Associates Consulting Engineers, Inc. reserves all copyright rights, but
> grants a temporary license to the recipient to use the materials contained in the
> attached computer data file for use in development of recipient's work associated
> with this project. Stock & Associates Consulting Engineers, Inc. does not warrant
> the accuracy of any information contained on said data file. Stock & Associates
> Consulting Engineers, Inc. assumes no liability for unauthorized alterations and
> alterations to the information contained herein.

--
/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://ourworld.compuserve.com/homepages/tonyt */
/*********************************************************/
0 Likes