• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    Visual LISP, AutoLISP and General Customization

    Reply
    Member
    Posts: 3
    Registered: ‎10-09-2007

    Select all 3DPolylines with same Vertex Z values

    202 Views, 7 Replies
    06-17-2012 02:11 PM

    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

    Please use plain text.
    *Expert Elite*
    Posts: 2,065
    Registered: ‎11-24-2009

    Re: Select all 3DPolylines with same Vertex Z values

    06-17-2012 10:08 PM 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?

     

    Please use plain text.
    Distinguished Contributor
    Posts: 106
    Registered: ‎02-06-2007

    Re: Select all 3DPolylines with same Vertex Z values

    06-18-2012 02:17 AM 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.

     

    Please use plain text.
    Member
    Posts: 3
    Registered: ‎10-09-2007

    Re: Select all 3DPolylines with same Vertex Z values

    06-18-2012 02:26 AM in reply to: jalmeida

    It works just fine!

    Thanks a lot.

     

    Julio Almeida

    Please use plain text.
    Valued Mentor
    _Tharwat
    Posts: 460
    Registered: ‎07-02-2010

    Re: Select all 3DPolylines with same Vertex Z values

    06-18-2012 02:52 AM in reply to: jalmeida

    Late to the party .... :smileyhappy:

     

    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)
    )
    
    

     

    Please use plain text.
    *Expert Elite*
    Posts: 2,065
    Registered: ‎11-24-2009

    Re: Select all 3DPolylines with same Vertex Z values

    06-18-2012 03:50 AM 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.

     

     

     

    Please use plain text.
    Active Contributor
    MetroVancouverDrafting
    Posts: 35
    Registered: ‎06-29-2010

    Re: Select all 3DPolylines with same Vertex Z values

    06-18-2012 10:31 AM in reply to: jalmeida

    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?

    Please use plain text.
    *Expert Elite*
    Kent1Cooper
    Posts: 4,080
    Registered: ‎09-13-2004

    Re: Select all 3DPolylines with same Vertex Z values

    06-18-2012 02:19 PM 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
    Please use plain text.