Jump to content
Stegee137

Select object with the highest elevation

Recommended Posts

Stegee137

I have a drawing that contains 1000's of LWPOLYLINES (with elevation) and CIRCLES (with thickness). I use the following LISP routine that I found a while ago on another forum to find the highest elevation/thickness value within a selection. 

 

(defun c:Max (/ ss i a b lst)
  (if (setq ss (ssget))
    (progn (repeat (setq i (sslength ss))
             (vla-getboundingbox (vlax-ename->vla-object (ssname ss (setq i (1- i)))) 'a 'b)
             (setq lst (cons (caddr (vlax-safearray->list a))
                             (cons (caddr (vlax-safearray->list b)) lst)
                       )
             )
           )
           (alert (strcat "Maximum Elevation: "
                          (rtos (apply 'max lst))
                  )
           )
    )
  )
  (princ)
)

The LISP works well but what I would like to be able to do is select all lines and/or circles with the maximum elevation within my selection area. Do any of you guys know how I might be able to adapt the LISP above to do this?

 

Many thanks

Share this post


Link to post
Share on other sites
fuccaro
(defun c:MaxZ( / ss0 ls i Zmax)
  (setq ss0 (ssget (list (cons 0 "Lwpolyline"))) ls nil i -1)
  (repeat (sslength ss0)
    (setq ls (cons (ssname ss0 (setq i (1+ i))) ls)))
  (setq ls1 (vl-sort ls (function (lambda (a b) (> (cdr (assoc 38 (entget a))) (cdr (assoc 38 (entget b))))))))
  (setq Zmax (cdr (assoc 38 (entget (car ls1)))) ss (ssadd) i -1 fuzz 0.1)
  (while (equal Zmax (cdr (assoc 38 (entget (setq en (nth (setq i (1+ i)) ls1))))) fuzz)
    (ssadd en ss))
  )

This should place all the polylines at maximum Z in the selection set ss. You may wish to adjust the fuzz distance (I set it to 0.1), so the program will find all the polylines "around" the Zmax

Share this post


Link to post
Share on other sites
Stegee137

Many thanks fuccaro. This only works with polylines whereas my dataset contains polylines and circles. I want to be able to select the highest object which may be a polyline (elevation) or a circle (thickness) or both. Do you think that will be possible?

Share this post


Link to post
Share on other sites
fuccaro

Yes, it's possible. I will change the code to add the circle things. I was waiting to see if I am walking in the right direction. I will try to do it today.

Share this post


Link to post
Share on other sites
Stegee137

Much appreciated fuccaro. Yes, I think so. Basically I am assessing 1000's of lines and circles. My LISP tells me what the highest value is but I need to know where it is too hence why I would like everything with that Max Z value to be selected.

Share this post


Link to post
Share on other sites
fuccaro
(defun c:MaxZ( / )
  (setq ss0 (ssget (list (cons 0 "Lwpolyline,circle"))) ls nil i -1)
  (repeat (sslength ss0)
    (setq en (ssname ss0 (setq i (1+ i)))
	  cir (= "CIRCLE" (cdr (assoc 0 (setq el (entget en)))))
	  elev (if cir (car (reverse (assoc 10 el))) (cdr (assoc 38 el)))
	 ls (cons (cons en elev) ls))
    )
  (setq ls1 (vl-sort ls '(lambda (a b) (> (cdr a) (cdr b)))))
  (setq Zmax (cdar ls1) ss (ssadd) i -1 fuzz 0.1)
  (while (equal Zmax (cdr (nth (setq i (1+ i)) ls1)) fuzz)
    (ssadd (car (nth i ls1)) ss))
  (princ (strcat "Max z= " (rtos Zmax)))
  (princ)
  )

 

Share this post


Link to post
Share on other sites
Stegee137

Thank you. I have just tried this but it is returning a max z value of 0 for all circles. It works correctly for the polylines but doesn't seem to select the polyline with the highest value afterwards. Am I doing something wrong?

Share this post


Link to post
Share on other sites
Lee Mac

Assuming that you are genuinely referring to the thickness property of a circle (i.e. DXF group 39), as opposed to the elevation of the centre, try the following:

(defun c:selhigh ( / e i l m r s x z )
    (if (setq s (ssget '((0 . "LWPOLYLINE,CIRCLE"))))
        (progn
            (repeat (setq i (sslength s))
                (setq i (1- i)
                      e (ssname s i)
                      x (entget e)
                )
                (if (= "CIRCLE" (cdr (assoc 0 x)))
                    (setq z (cond ((cdr (assoc 39 x)))(0)))
                    (setq z (cdr (assoc 38 x)))
                )
                (if (< m z) (setq m z))
                (setq l (cons (cons z e) l))
            )
            (setq r (ssadd))
            (foreach x l
                (if (equal (car x) m 1e-8)
                    (ssadd (cdr x) r)
                )
            )
            (sssetfirst nil r)
        )
    )
    (princ)
)

 

Share this post


Link to post
Share on other sites
Stegee137

That is perfect Lee Mac! Does exactly what I wanted. Many thanks!!

Share this post


Link to post
Share on other sites
Stegee137

Sorry Lee Mac, one thing I forgot to ask - in my original LISP it had an alert to tell me what the highest value is. Is it possible to add that to this LISP?

Share this post


Link to post
Share on other sites
Lee Mac
15 minutes ago, Stegee137 said:

That is perfect Lee Mac! Does exactly what I wanted. Many thanks!!

 

Excellent - you're most welcome.

 

11 minutes ago, Stegee137 said:

Sorry Lee Mac, one thing I forgot to ask - in my original LISP it had an alert to tell me what the highest value is. Is it possible to add that to this LISP?

 

Certainly - the following will print the value to the command-line:

(defun c:selhigh ( / e i l m r s x z )
    (if (setq s (ssget '((0 . "LWPOLYLINE,CIRCLE"))))
        (progn
            (repeat (setq i (sslength s))
                (setq i (1- i)
                      e (ssname s i)
                      x (entget e)
                )
                (if (= "CIRCLE" (cdr (assoc 0 x)))
                    (setq z (cond ((cdr (assoc 39 x)))(0)))
                    (setq z (cdr (assoc 38 x)))
                )
                (if (< m z) (setq m z))
                (setq l (cons (cons z e) l))
            )
            (setq r (ssadd))
            (foreach x l
                (if (equal (car x) m 1e-8)
                    (ssadd (cdr x) r)
                )
            )
            (princ (strcat "Maximum elevation/thickness: " (rtos m)))
            (sssetfirst nil r)
        )
    )
    (princ)
)

Change (princ (strcat ... )) to (alert (strcat ... )) if you really want a modal dialog.

Edited by Lee Mac

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...