Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Select all 3DPolylines with same Vertex Z values

11 REPLIES 11
Reply
Message 1 of 12
jalmeida
1963 Views, 11 Replies

Select all 3DPolylines with same Vertex Z values

Hi,

 

I need to wright a routine in autolisp that selects all 3Dpolylines with the same vertex Z value.

Qselect as no transparent mode and filter doesn't work.

Can anyone help me,

Thanks,

 

Julio Almeida

11 REPLIES 11
Message 2 of 12
pbejse
in reply to: jalmeida


@jalmeida wrote:

Hi,

 

I need to wright a routine in autolisp that selects all 3Dpolylines with the same vertex Z value.

Qselect as no transparent mode and filter doesn't work.

Can anyone help me,

Thanks,

 

Julio Almeida


That would be a handful Julio. that would mean the 3Dpolylines would ahve to be the same number of vertices.

e.g.( (2.4 5.6 23.0)(5.2 6.3 24.0)(8.2 4.6 21.0)) is a match with ((4.1 2.8 23.0)(2.2 5.3 24.0)(1.2 7.3 21.0))  other than that its not?

 

Message 3 of 12
phanaem
in reply to: jalmeida

Hi Julio

I hope I understood correctly your request...

 

(defun C:TEST ( / get_z z i ss e)
  (defun get_z (e / lst z_lst z)
  (setq lst (vlax-get (vlax-ename->vla-object e) 'coordinates))
  (while lst
    (setq z_lst (cons (caddr lst) z_lst)
          lst (cdddr lst))
    )
  (setq z (car z_lst))
  (if
    (vl-every '(lambda (x) (= z x)) (cdr z_lst))
    z
    )
  )
  
  (if
    (or
      (setq z (getreal "\nElevation [Object]: "))
      (progn
        (princ "\nSelect 3DPolyline: ")
        (setq z (ssget "_:E:S" '((0 . "POLYLINE"))))
        )
      )
    (if
      (or
        (numberp z)
        (setq z (get_z (ssname z 0)))
        )
      (repeat
        (setq i (sslength (setq ss (ssget "X" '((0 . "POLYLINE"))))))
        (if (not (= z (get_z (setq e (ssname ss (setq i (1- i)))))))
          (ssdel e ss)
          )
        )
      )
    )
  (sssetfirst nil ss)
  (princ)
  )

 You can input a value for Z when  prompted, or select a 3DPolyline. All other 3DPolylines with the same z value are selected on screen.

 

Message 4 of 12
jalmeida
in reply to: jalmeida

It works just fine!

Thanks a lot.

 

Julio Almeida

Message 5 of 12
_Tharwat
in reply to: jalmeida

Late to the party .... Smiley Happy

 

Would this be of any assistance ..... ?

 

(defun c:Test (/ s v ss i j q n sn)
  ;;;; Tharwat 18. June. 2012    ;;;;
  (if (and (setq s (ssadd)
                 v (getdist "\n Specify Z value :")
           )
           (setq ss (ssget "_x" '((0 . "*POLYLINE"))))
      )
    (repeat (setq i (sslength ss))
      (setq j -1 q 0  n nil)
      (setq sn (ssname ss (setq i (1- i))))
      (if (eq (cdr (assoc 100 (reverse (entget sn)))) "AcDb3dPolyline")
        (progn
          (repeat (setq n (1+ (fix (vlax-curve-getendparam sn))))
            (if
              (equal
                (last (vlax-curve-getpointatparam sn (setq j (1+ j))))  v)
               (setq q (1+ q))
            )
          )
          (if (eq q n) (ssadd sn s)
          )
        )
      )
    )
    (princ)
  )
  (if (> (sslength s) 0) (sssetfirst nil s)
  )
  (princ)
)

 

Message 6 of 12
pbejse
in reply to: jalmeida


@jalmeida wrote:

It works just fine!

 

Julio Almeida


For a while there i thought you would be using 3DPolylines (Polyline) for a reason. like varying Z values along the curve

It appears that constant Z value (Elevation)  is what you're refering to.

 

 

 

Message 7 of 12

Be more specific.

Same Z in the first  vertex of two plines?

Same Z in the first and last vertex of the same pline?

Do you need to select plines with different count of vertexes?

Message 8 of 12
Kent1Cooper
in reply to: jalmeida


@jalmeida wrote:

.... 

I need to wright a routine in autolisp that selects all 3Dpolylines with the same vertex Z value.

Qselect as no transparent mode and filter doesn't work.

....


I wasn't sure how to interpret the question, exactly, and I may have it wrong considering the other responses.  But here are some alternatives.

 

They both use a different way of extracting the Z coordinates as every third number from the 'Coordinates list, a little more directly perhaps than paring down that list with each number extracted or looking separately at each vertex.  And they take advantage of the fact that unlike (eq), the (=) function can compare a whole list full of items, so each one doesn't need to be compared separately.

 

The first one will do what I thought you were originally asking, namely, find all 3DPolylines "with the same vertex Z value" within themselves, that is, all that are planar and parallel to the XY plane, regardless of what each one's Z elevation may be or whether any are at the same Z elevation as each other.  The second one asks the User for an elevation and finds all those that match it throughout.

 

(defun C:3DPP (/ 3DPss 3DPP 3DP coords Zs inc)
; = 3DPolylines that are Planar [parallel to WCS XY plane] within themselves
  (setq
    3DPss (ssget "_X" '((0 . "POLYLINE"))); all "heavy" Polylines [including 2D]
    3DPP (ssadd); start empty set
  ); setq
  (repeat (sslength 3DPss)
    (setq
      3DP (ssname 3DPss 0)
      coords (vlax-get (vlax-ename->vla-object 3DP) 'Coordinates)
      Zs nil inc nil ; reset for each
    ); setq
    (if
      (and
        (= (cdr (assoc 100 (reverse (entget 3DP)))) "AcDb3dPolyline"); only 3D ones
        (repeat (/ (length coords) 3); every third number = Z coordinates
          (setq Zs (cons (nth (setq inc (+ 3 (cond (inc) (-1)))) coords) Zs))
        ); repeat
        (apply '= Zs); all Z coordinates are equal
      ); and
      (ssadd 3DP 3DPP); put in set of qualifying ones
    ); if
    (ssdel 3DP 3DPss)
  ); repeat
  (if (> (sslength 3DPP) 0) (sssetfirst nil 3DPP))
); defun

 

(defun C:3DPPU (/ elev 3DPss 3DPP 3DP coords Zs inc)
; = 3DPolylines that are Planar [parallel to WCS XY plane] and at User-specified elevation
  (setq
    elev (getdist "\nSpecify elevation of 3DPolylines to find: ")
    3DPss (ssget "_X" '((0 . "POLYLINE"))); all "heavy" Polylines [including 2D]
    3DPP (ssadd); start empty set
  ); setq
  (repeat (sslength 3DPss)
    (setq
      3DP (ssname 3DPss 0)
      coords (vlax-get (vlax-ename->vla-object 3DP) 'Coordinates)
      Zs nil inc nil ; reset for each Polyline
    ); setq
    (if
      (and
        (= (cdr (assoc 100 (reverse (entget 3DP)))) "AcDb3dPolyline"); only 3D ones
        (repeat (/ (length coords) 3); every third number = Z coordinates
          (setq Zs (cons (nth (setq inc (+ 3 (cond (inc) (-1)))) coords) Zs))
        ); repeat
        (apply '= (cons elev Zs)); all Z coordinates equal to specified elevation
      ); and
      (ssadd 3DP 3DPP); put in set of qualifying ones
    ); if
    (ssdel 3DP 3DPss)
  ); repeat
  (if (> (sslength 3DPP) 0) (sssetfirst nil 3DPP))
); defun

 

HOWEVER, I wonder about something that could plague either of these routines and other people's solutions.  A lot of times, when comparing numerical values with (=) or (eq), you can run into trouble if the values aren't really exactly equal.  In the case of drawn 3DPolylines, if they were drawn with the current working plane truly parallel to the WCS XY plane, they should work.  But if they were, for instance, drawn by some routine, and any of the vertext locations are the result of calculations, or even without that if object snap was involved, it could be that tiny rounding variabilities will cause (=) or (eq) to consider things not to be at the same Z coordinate that you think should be considered the same, and you should really use (equal) with a very small fuzz factor.  If that's a potential problem, Z values would need to be compared one at a time, since (equal) can't compare more than two numbers the way (=) can, so my routines wouldn't do the job.

Kent Cooper, AIA
Message 9 of 12
jason.turner
in reply to: Kent1Cooper

Hi there.

 

Newbie here. Thank you for the lisps. I have them loaded fine, but I can't find the magic command to make them execute. Could you please assist?

 

Thanks in anticipation.

Message 10 of 12
Kent1Cooper
in reply to: jason.turner


@jason.turner wrote:

.... I have them loaded fine, but I can't find the magic command to make them execute. ....



The part immediately after  (defun C:  is the command name -- just type that in as any other command name.  In these cases, 3DPP or 3DPPU.

Kent Cooper, AIA
Message 11 of 12
Sea-Haven
in reply to: jalmeida

Had a play with using ssget and filters

 

Thanks to Tharwat for a version 

(setq ss (ssget "X" (list '(0 . "line") (cons -4 (strcat "*,*," "="))(list 10 0.0 0.0 Z))))

 

What I did find is that other objects use other methods so above could be expanded to work with other objects but it will be and or's etc.

 

Line & circle & arc use assoc 10  '(0 . "line,arc,circle")

LWpolyline use assoc 38 for elev

3dpoly extended data

 

 

 

 

 

 

Message 12 of 12
debbiecameron
in reply to: phanaem

Brilliant! Thank you

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost